├── TheArtOFMultiprocessorProgramming ├── Lock │ ├── CLHLock.java │ ├── MCSLock.java │ ├── TASLock.java │ ├── ArrayLock.java │ ├── TTASLock.java │ ├── BackoffLock.java │ ├── TimeOutLock.java │ ├── CompositeLock.java │ ├── CompositeFastPathLock.java │ └── Backoff.java ├── MonitorsAndBlockingSynchronization │ ├── Semaphore.java │ ├── FifoReadWriteLock.java │ ├── SimpleReadWriteLock.java │ └── SimpleReentrantLock.java ├── locks │ ├── AbstractOwnableSynchronizer.java │ ├── package-info.java │ ├── ReadWriteLock.java │ ├── LockSupport.java │ └── Lock.java ├── concurrent │ └── atomic │ │ ├── AtomicReference.java │ │ ├── AtomicBoolean.java │ │ ├── AtomicReferenceArray.java │ │ ├── AtomicInteger.java │ │ ├── AtomicStampedReference.java │ │ ├── AtomicMarkableReference.java │ │ ├── AtomicLong.java │ │ ├── AtomicLongArray.java │ │ ├── AtomicIntegerArray.java │ │ ├── package-info.java │ │ ├── AtomicReferenceFieldUpdater.java │ │ ├── AtomicIntegerFieldUpdater.java │ │ └── AtomicLongFieldUpdater.java ├── TheArtOFMultiprocessorProgramming.vcxproj.filters ├── TheArtOFMultiprocessorProgramming.vcxproj ├── park.hpp └── park.cpp ├── README.md ├── TheArtOFMultiprocessorProgramming.sln ├── .gitattributes └── .gitignore /TheArtOFMultiprocessorProgramming/Lock/CLHLock.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zouxiaohang/TheArtOFMultiprocessorProgramming/HEAD/TheArtOFMultiprocessorProgramming/Lock/CLHLock.java -------------------------------------------------------------------------------- /TheArtOFMultiprocessorProgramming/Lock/MCSLock.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zouxiaohang/TheArtOFMultiprocessorProgramming/HEAD/TheArtOFMultiprocessorProgramming/Lock/MCSLock.java -------------------------------------------------------------------------------- /TheArtOFMultiprocessorProgramming/Lock/TASLock.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zouxiaohang/TheArtOFMultiprocessorProgramming/HEAD/TheArtOFMultiprocessorProgramming/Lock/TASLock.java -------------------------------------------------------------------------------- /TheArtOFMultiprocessorProgramming/Lock/ArrayLock.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zouxiaohang/TheArtOFMultiprocessorProgramming/HEAD/TheArtOFMultiprocessorProgramming/Lock/ArrayLock.java -------------------------------------------------------------------------------- /TheArtOFMultiprocessorProgramming/Lock/TTASLock.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zouxiaohang/TheArtOFMultiprocessorProgramming/HEAD/TheArtOFMultiprocessorProgramming/Lock/TTASLock.java -------------------------------------------------------------------------------- /TheArtOFMultiprocessorProgramming/Lock/BackoffLock.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zouxiaohang/TheArtOFMultiprocessorProgramming/HEAD/TheArtOFMultiprocessorProgramming/Lock/BackoffLock.java -------------------------------------------------------------------------------- /TheArtOFMultiprocessorProgramming/Lock/TimeOutLock.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zouxiaohang/TheArtOFMultiprocessorProgramming/HEAD/TheArtOFMultiprocessorProgramming/Lock/TimeOutLock.java -------------------------------------------------------------------------------- /TheArtOFMultiprocessorProgramming/Lock/CompositeLock.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zouxiaohang/TheArtOFMultiprocessorProgramming/HEAD/TheArtOFMultiprocessorProgramming/Lock/CompositeLock.java -------------------------------------------------------------------------------- /TheArtOFMultiprocessorProgramming/Lock/CompositeFastPathLock.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zouxiaohang/TheArtOFMultiprocessorProgramming/HEAD/TheArtOFMultiprocessorProgramming/Lock/CompositeFastPathLock.java -------------------------------------------------------------------------------- /TheArtOFMultiprocessorProgramming/MonitorsAndBlockingSynchronization/Semaphore.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zouxiaohang/TheArtOFMultiprocessorProgramming/HEAD/TheArtOFMultiprocessorProgramming/MonitorsAndBlockingSynchronization/Semaphore.java -------------------------------------------------------------------------------- /TheArtOFMultiprocessorProgramming/MonitorsAndBlockingSynchronization/FifoReadWriteLock.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zouxiaohang/TheArtOFMultiprocessorProgramming/HEAD/TheArtOFMultiprocessorProgramming/MonitorsAndBlockingSynchronization/FifoReadWriteLock.java -------------------------------------------------------------------------------- /TheArtOFMultiprocessorProgramming/MonitorsAndBlockingSynchronization/SimpleReadWriteLock.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zouxiaohang/TheArtOFMultiprocessorProgramming/HEAD/TheArtOFMultiprocessorProgramming/MonitorsAndBlockingSynchronization/SimpleReadWriteLock.java -------------------------------------------------------------------------------- /TheArtOFMultiprocessorProgramming/MonitorsAndBlockingSynchronization/SimpleReentrantLock.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zouxiaohang/TheArtOFMultiprocessorProgramming/HEAD/TheArtOFMultiprocessorProgramming/MonitorsAndBlockingSynchronization/SimpleReentrantLock.java -------------------------------------------------------------------------------- /TheArtOFMultiprocessorProgramming/Lock/Backoff.java: -------------------------------------------------------------------------------- 1 | import java.util.Random; 2 | 3 | public class Backoff{ 4 | final int minDelay, maxDelay; 5 | int limit; 6 | final Random random; 7 | 8 | public Backoff(int min, int max){ 9 | minDelay = min; 10 | maxDelay = max; 11 | limit = min; 12 | random = new Random(); 13 | } 14 | public void backoff() throws InterruptedException{ 15 | int delay = random.nextInt(limit); 16 | limit = Math.min(maxDelay, 2 * limit); 17 | Thread.sleep(delay); 18 | } 19 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | The Art Of Multiprocessor Programming 2 | ================================= 3 | 4 | 多处理器编程的艺术 5 | ================== 6 | 7 | #####完成《多处理器编程的艺术》这本书上的所有示例代码,并给出自己的评注,包括对代码的注释、分析和书中示例代码出现的bug 8 | 9 | * Chapter 7: 10 | * TASLock 11 | * TTASLock 12 | * ArrayLock 13 | * BackoffLock 14 | * CLHLock 15 | * MCSLock 16 | * TimeOutLock 17 | * CompositeLock 18 | * CompositeFastPathLock 19 | * Chapter 8: 20 | * SimpleReadWriteLock 21 | * FifoReadWriteLock 22 | * Semaphore 23 | * SimpleReentrantLock 24 | -------------------------------------------------------------------------------- /TheArtOFMultiprocessorProgramming.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Express 2013 for Windows Desktop 4 | VisualStudioVersion = 12.0.30723.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TheArtOFMultiprocessorProgramming", "TheArtOFMultiprocessorProgramming\TheArtOFMultiprocessorProgramming.vcxproj", "{0218C742-7542-449E-BA33-98E9BB64193D}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Win32 = Debug|Win32 11 | Release|Win32 = Release|Win32 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {0218C742-7542-449E-BA33-98E9BB64193D}.Debug|Win32.ActiveCfg = Debug|Win32 15 | {0218C742-7542-449E-BA33-98E9BB64193D}.Debug|Win32.Build.0 = Debug|Win32 16 | {0218C742-7542-449E-BA33-98E9BB64193D}.Release|Win32.ActiveCfg = Release|Win32 17 | {0218C742-7542-449E-BA33-98E9BB64193D}.Release|Win32.Build.0 = Release|Win32 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.sln.docstates 8 | 9 | # Build results 10 | 11 | [Dd]ebug/ 12 | [Rr]elease/ 13 | x64/ 14 | build/ 15 | [Bb]in/ 16 | [Oo]bj/ 17 | 18 | # Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets 19 | !packages/*/build/ 20 | 21 | # MSTest test Results 22 | [Tt]est[Rr]esult*/ 23 | [Bb]uild[Ll]og.* 24 | 25 | *_i.c 26 | *_p.c 27 | *.ilk 28 | *.meta 29 | *.obj 30 | *.pch 31 | *.pdb 32 | *.pgc 33 | *.pgd 34 | *.rsp 35 | *.sbr 36 | *.tlb 37 | *.tli 38 | *.tlh 39 | *.tmp 40 | *.tmp_proj 41 | *.log 42 | *.vspscc 43 | *.vssscc 44 | .builds 45 | *.pidb 46 | *.log 47 | *.scc 48 | 49 | # Visual C++ cache files 50 | ipch/ 51 | *.aps 52 | *.ncb 53 | *.opensdf 54 | *.sdf 55 | *.cachefile 56 | 57 | # Visual Studio profiler 58 | *.psess 59 | *.vsp 60 | *.vspx 61 | 62 | # Guidance Automation Toolkit 63 | *.gpState 64 | 65 | # ReSharper is a .NET coding add-in 66 | _ReSharper*/ 67 | *.[Rr]e[Ss]harper 68 | 69 | # TeamCity is a build add-in 70 | _TeamCity* 71 | 72 | # DotCover is a Code Coverage Tool 73 | *.dotCover 74 | 75 | # NCrunch 76 | *.ncrunch* 77 | .*crunch*.local.xml 78 | 79 | # Installshield output folder 80 | [Ee]xpress/ 81 | 82 | # DocProject is a documentation generator add-in 83 | DocProject/buildhelp/ 84 | DocProject/Help/*.HxT 85 | DocProject/Help/*.HxC 86 | DocProject/Help/*.hhc 87 | DocProject/Help/*.hhk 88 | DocProject/Help/*.hhp 89 | DocProject/Help/Html2 90 | DocProject/Help/html 91 | 92 | # Click-Once directory 93 | publish/ 94 | 95 | # Publish Web Output 96 | *.Publish.xml 97 | 98 | # NuGet Packages Directory 99 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line 100 | #packages/ 101 | 102 | # Windows Azure Build Output 103 | csx 104 | *.build.csdef 105 | 106 | # Windows Store app package directory 107 | AppPackages/ 108 | 109 | # Others 110 | sql/ 111 | *.Cache 112 | ClientBin/ 113 | [Ss]tyle[Cc]op.* 114 | ~$* 115 | *~ 116 | *.dbmdl 117 | *.[Pp]ublish.xml 118 | *.pfx 119 | *.publishsettings 120 | 121 | # RIA/Silverlight projects 122 | Generated_Code/ 123 | 124 | # Backup & report files from converting an old project file to a newer 125 | # Visual Studio version. Backup files are not needed, because we have git ;-) 126 | _UpgradeReport_Files/ 127 | Backup*/ 128 | UpgradeLog*.XML 129 | UpgradeLog*.htm 130 | 131 | # SQL Server files 132 | App_Data/*.mdf 133 | App_Data/*.ldf 134 | 135 | 136 | #LightSwitch generated files 137 | GeneratedArtifacts/ 138 | _Pvt_Extensions/ 139 | ModelManifest.xml 140 | 141 | # ========================= 142 | # Windows detritus 143 | # ========================= 144 | 145 | # Windows image file caches 146 | Thumbs.db 147 | ehthumbs.db 148 | 149 | # Folder config file 150 | Desktop.ini 151 | 152 | # Recycle Bin used on file shares 153 | $RECYCLE.BIN/ 154 | 155 | # Mac desktop service store files 156 | .DS_Store 157 | -------------------------------------------------------------------------------- /TheArtOFMultiprocessorProgramming/locks/AbstractOwnableSynchronizer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 | * 4 | * This code is free software; you can redistribute it and/or modify it 5 | * under the terms of the GNU General Public License version 2 only, as 6 | * published by the Free Software Foundation. Oracle designates this 7 | * particular file as subject to the "Classpath" exception as provided 8 | * by Oracle in the LICENSE file that accompanied this code. 9 | * 10 | * This code is distributed in the hope that it will be useful, but WITHOUT 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * version 2 for more details (a copy is included in the LICENSE file that 14 | * accompanied this code). 15 | * 16 | * You should have received a copy of the GNU General Public License version 17 | * 2 along with this work; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 | * 20 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 | * or visit www.oracle.com if you need additional information or have any 22 | * questions. 23 | */ 24 | 25 | /* 26 | * This file is available under and governed by the GNU General Public 27 | * License version 2 only, as published by the Free Software Foundation. 28 | * However, the following notice accompanied the original version of this 29 | * file: 30 | * 31 | * Written by Doug Lea with assistance from members of JCP JSR-166 32 | * Expert Group and released to the public domain, as explained at 33 | * http://creativecommons.org/publicdomain/zero/1.0/ 34 | */ 35 | 36 | package java.util.concurrent.locks; 37 | 38 | /** 39 | * A synchronizer that may be exclusively owned by a thread. This 40 | * class provides a basis for creating locks and related synchronizers 41 | * that may entail a notion of ownership. The 42 | * AbstractOwnableSynchronizer class itself does not manage or 43 | * use this information. However, subclasses and tools may use 44 | * appropriately maintained values to help control and monitor access 45 | * and provide diagnostics. 46 | * 47 | * @since 1.6 48 | * @author Doug Lea 49 | */ 50 | public abstract class AbstractOwnableSynchronizer 51 | implements java.io.Serializable { 52 | 53 | /** Use serial ID even though all fields transient. */ 54 | private static final long serialVersionUID = 3737899427754241961L; 55 | 56 | /** 57 | * Empty constructor for use by subclasses. 58 | */ 59 | protected AbstractOwnableSynchronizer() { } 60 | 61 | /** 62 | * The current owner of exclusive mode synchronization. 63 | */ 64 | private transient Thread exclusiveOwnerThread; 65 | 66 | /** 67 | * Sets the thread that currently owns exclusive access. A 68 | * null argument indicates that no thread owns access. 69 | * This method does not otherwise impose any synchronization or 70 | * volatile field accesses. 71 | */ 72 | protected final void setExclusiveOwnerThread(Thread t) { 73 | exclusiveOwnerThread = t; 74 | } 75 | 76 | /** 77 | * Returns the thread last set by 78 | * setExclusiveOwnerThread, or null if never 79 | * set. This method does not otherwise impose any synchronization 80 | * or volatile field accesses. 81 | * @return the owner thread 82 | */ 83 | protected final Thread getExclusiveOwnerThread() { 84 | return exclusiveOwnerThread; 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /TheArtOFMultiprocessorProgramming/locks/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 | * 4 | * This code is free software; you can redistribute it and/or modify it 5 | * under the terms of the GNU General Public License version 2 only, as 6 | * published by the Free Software Foundation. Oracle designates this 7 | * particular file as subject to the "Classpath" exception as provided 8 | * by Oracle in the LICENSE file that accompanied this code. 9 | * 10 | * This code is distributed in the hope that it will be useful, but WITHOUT 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | * version 2 for more details (a copy is included in the LICENSE file that 14 | * accompanied this code). 15 | * 16 | * You should have received a copy of the GNU General Public License version 17 | * 2 along with this work; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 | * 20 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 | * or visit www.oracle.com if you need additional information or have any 22 | * questions. 23 | */ 24 | 25 | /* 26 | * This file is available under and governed by the GNU General Public 27 | * License version 2 only, as published by the Free Software Foundation. 28 | * However, the following notice accompanied the original version of this 29 | * file: 30 | * 31 | * Written by Doug Lea with assistance from members of JCP JSR-166 32 | * Expert Group and released to the public domain, as explained at 33 | * http://creativecommons.org/publicdomain/zero/1.0/ 34 | */ 35 | 36 | /** 37 | * Interfaces and classes providing a framework for locking and waiting 38 | * for conditions that is distinct from built-in synchronization and 39 | * monitors. The framework permits much greater flexibility in the use of 40 | * locks and conditions, at the expense of more awkward syntax. 41 | * 42 | *
The {@link java.util.concurrent.locks.Lock} interface supports 43 | * locking disciplines that differ in semantics (reentrant, fair, etc), 44 | * and that can be used in non-block-structured contexts including 45 | * hand-over-hand and lock reordering algorithms. The main implementation 46 | * is {@link java.util.concurrent.locks.ReentrantLock}. 47 | * 48 | *
The {@link java.util.concurrent.locks.ReadWriteLock} interface 49 | * similarly defines locks that may be shared among readers but are 50 | * exclusive to writers. Only a single implementation, {@link 51 | * java.util.concurrent.locks.ReentrantReadWriteLock}, is provided, since 52 | * it covers most standard usage contexts. But programmers may create 53 | * their own implementations to cover nonstandard requirements. 54 | * 55 | *
The {@link java.util.concurrent.locks.Condition} interface 56 | * describes condition variables that may be associated with Locks. 57 | * These are similar in usage to the implicit monitors accessed using 58 | * {@code Object.wait}, but offer extended capabilities. 59 | * In particular, multiple {@code Condition} objects may be associated 60 | * with a single {@code Lock}. To avoid compatibility issues, the 61 | * names of {@code Condition} methods are different from the 62 | * corresponding {@code Object} versions. 63 | * 64 | *
The {@link java.util.concurrent.locks.AbstractQueuedSynchronizer}
65 | * class serves as a useful superclass for defining locks and other
66 | * synchronizers that rely on queuing blocked threads. The {@link
67 | * java.util.concurrent.locks.AbstractQueuedLongSynchronizer} class
68 | * provides the same functionality but extends support to 64 bits of
69 | * synchronization state. Both extend class {@link
70 | * java.util.concurrent.locks.AbstractOwnableSynchronizer}, a simple
71 | * class that helps record the thread currently holding exclusive
72 | * synchronization. The {@link java.util.concurrent.locks.LockSupport}
73 | * class provides lower-level blocking and unblocking support that is
74 | * useful for those developers implementing their own customized lock
75 | * classes.
76 | *
77 | * @since 1.5
78 | */
79 | package java.util.concurrent.locks;
80 |
--------------------------------------------------------------------------------
/TheArtOFMultiprocessorProgramming/concurrent/atomic/AtomicReference.java:
--------------------------------------------------------------------------------
1 | /*
2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3 | *
4 | * This code is free software; you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License version 2 only, as
6 | * published by the Free Software Foundation. Oracle designates this
7 | * particular file as subject to the "Classpath" exception as provided
8 | * by Oracle in the LICENSE file that accompanied this code.
9 | *
10 | * This code is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 | * version 2 for more details (a copy is included in the LICENSE file that
14 | * accompanied this code).
15 | *
16 | * You should have received a copy of the GNU General Public License version
17 | * 2 along with this work; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 | *
20 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 | * or visit www.oracle.com if you need additional information or have any
22 | * questions.
23 | */
24 |
25 | /*
26 | * This file is available under and governed by the GNU General Public
27 | * License version 2 only, as published by the Free Software Foundation.
28 | * However, the following notice accompanied the original version of this
29 | * file:
30 | *
31 | * Written by Doug Lea with assistance from members of JCP JSR-166
32 | * Expert Group and released to the public domain, as explained at
33 | * http://creativecommons.org/publicdomain/zero/1.0/
34 | */
35 |
36 | package java.util.concurrent.atomic;
37 | import sun.misc.Unsafe;
38 |
39 | /**
40 | * An object reference that may be updated atomically. See the {@link
41 | * java.util.concurrent.atomic} package specification for description
42 | * of the properties of atomic variables.
43 | * @since 1.5
44 | * @author Doug Lea
45 | * @param May fail spuriously
122 | * and does not provide ordering guarantees, so is only rarely an
123 | * appropriate alternative to {@code compareAndSet}.
124 | *
125 | * @param expect the expected value
126 | * @param update the new value
127 | * @return true if successful.
128 | */
129 | public final boolean weakCompareAndSet(V expect, V update) {
130 | return unsafe.compareAndSwapObject(this, valueOffset, expect, update);
131 | }
132 |
133 | /**
134 | * Atomically sets to the given value and returns the old value.
135 | *
136 | * @param newValue the new value
137 | * @return the previous value
138 | */
139 | public final V getAndSet(V newValue) {
140 | while (true) {
141 | V x = get();
142 | if (compareAndSet(x, newValue))
143 | return x;
144 | }
145 | }
146 |
147 | /**
148 | * Returns the String representation of the current value.
149 | * @return the String representation of the current value.
150 | */
151 | public String toString() {
152 | return String.valueOf(get());
153 | }
154 |
155 | }
156 |
--------------------------------------------------------------------------------
/TheArtOFMultiprocessorProgramming/TheArtOFMultiprocessorProgramming.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 | May fail spuriously
109 | * and does not provide ordering guarantees, so is only rarely an
110 | * appropriate alternative to {@code compareAndSet}.
111 | *
112 | * @param expect the expected value
113 | * @param update the new value
114 | * @return true if successful.
115 | */
116 | public boolean weakCompareAndSet(boolean expect, boolean update) {
117 | int e = expect ? 1 : 0;
118 | int u = update ? 1 : 0;
119 | return unsafe.compareAndSwapInt(this, valueOffset, e, u);
120 | }
121 |
122 | /**
123 | * Unconditionally sets to the given value.
124 | *
125 | * @param newValue the new value
126 | */
127 | public final void set(boolean newValue) {
128 | value = newValue ? 1 : 0;
129 | }
130 |
131 | /**
132 | * Eventually sets to the given value.
133 | *
134 | * @param newValue the new value
135 | * @since 1.6
136 | */
137 | public final void lazySet(boolean newValue) {
138 | int v = newValue ? 1 : 0;
139 | unsafe.putOrderedInt(this, valueOffset, v);
140 | }
141 |
142 | /**
143 | * Atomically sets to the given value and returns the previous value.
144 | *
145 | * @param newValue the new value
146 | * @return the previous value
147 | */
148 | public final boolean getAndSet(boolean newValue) {
149 | for (;;) {
150 | boolean current = get();
151 | if (compareAndSet(current, newValue))
152 | return current;
153 | }
154 | }
155 |
156 | /**
157 | * Returns the String representation of the current value.
158 | * @return the String representation of the current value.
159 | */
160 | public String toString() {
161 | return Boolean.toString(get());
162 | }
163 |
164 | }
165 |
--------------------------------------------------------------------------------
/TheArtOFMultiprocessorProgramming/locks/ReadWriteLock.java:
--------------------------------------------------------------------------------
1 | /*
2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3 | *
4 | * This code is free software; you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License version 2 only, as
6 | * published by the Free Software Foundation. Oracle designates this
7 | * particular file as subject to the "Classpath" exception as provided
8 | * by Oracle in the LICENSE file that accompanied this code.
9 | *
10 | * This code is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 | * version 2 for more details (a copy is included in the LICENSE file that
14 | * accompanied this code).
15 | *
16 | * You should have received a copy of the GNU General Public License version
17 | * 2 along with this work; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 | *
20 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 | * or visit www.oracle.com if you need additional information or have any
22 | * questions.
23 | */
24 |
25 | /*
26 | * This file is available under and governed by the GNU General Public
27 | * License version 2 only, as published by the Free Software Foundation.
28 | * However, the following notice accompanied the original version of this
29 | * file:
30 | *
31 | * Written by Doug Lea with assistance from members of JCP JSR-166
32 | * Expert Group and released to the public domain, as explained at
33 | * http://creativecommons.org/publicdomain/zero/1.0/
34 | */
35 |
36 | package java.util.concurrent.locks;
37 |
38 | /**
39 | * A ReadWriteLock maintains a pair of associated {@link
40 | * Lock locks}, one for read-only operations and one for writing.
41 | * The {@link #readLock read lock} may be held simultaneously by
42 | * multiple reader threads, so long as there are no writers. The
43 | * {@link #writeLock write lock} is exclusive.
44 | *
45 | * All ReadWriteLock implementations must guarantee that
46 | * the memory synchronization effects of writeLock operations
47 | * (as specified in the {@link Lock} interface) also hold with respect
48 | * to the associated readLock. That is, a thread successfully
49 | * acquiring the read lock will see all updates made upon previous
50 | * release of the write lock.
51 | *
52 | * A read-write lock allows for a greater level of concurrency in
53 | * accessing shared data than that permitted by a mutual exclusion lock.
54 | * It exploits the fact that while only a single thread at a time (a
55 | * writer thread) can modify the shared data, in many cases any
56 | * number of threads can concurrently read the data (hence reader
57 | * threads).
58 | * In theory, the increase in concurrency permitted by the use of a read-write
59 | * lock will lead to performance improvements over the use of a mutual
60 | * exclusion lock. In practice this increase in concurrency will only be fully
61 | * realized on a multi-processor, and then only if the access patterns for
62 | * the shared data are suitable.
63 | *
64 | * Whether or not a read-write lock will improve performance over the use
65 | * of a mutual exclusion lock depends on the frequency that the data is
66 | * read compared to being modified, the duration of the read and write
67 | * operations, and the contention for the data - that is, the number of
68 | * threads that will try to read or write the data at the same time.
69 | * For example, a collection that is initially populated with data and
70 | * thereafter infrequently modified, while being frequently searched
71 | * (such as a directory of some kind) is an ideal candidate for the use of
72 | * a read-write lock. However, if updates become frequent then the data
73 | * spends most of its time being exclusively locked and there is little, if any
74 | * increase in concurrency. Further, if the read operations are too short
75 | * the overhead of the read-write lock implementation (which is inherently
76 | * more complex than a mutual exclusion lock) can dominate the execution
77 | * cost, particularly as many read-write lock implementations still serialize
78 | * all threads through a small section of code. Ultimately, only profiling
79 | * and measurement will establish whether the use of a read-write lock is
80 | * suitable for your application.
81 | *
82 | *
83 | * Although the basic operation of a read-write lock is straight-forward,
84 | * there are many policy decisions that an implementation must make, which
85 | * may affect the effectiveness of the read-write lock in a given application.
86 | * Examples of these policies include:
87 | * May fail spuriously
182 | * and does not provide ordering guarantees, so is only rarely an
183 | * appropriate alternative to {@code compareAndSet}.
184 | *
185 | * @param i the index
186 | * @param expect the expected value
187 | * @param update the new value
188 | * @return true if successful.
189 | */
190 | public final boolean weakCompareAndSet(int i, E expect, E update) {
191 | return compareAndSet(i, expect, update);
192 | }
193 |
194 | /**
195 | * Returns the String representation of the current values of array.
196 | * @return the String representation of the current values of array
197 | */
198 | public String toString() {
199 | int iMax = array.length - 1;
200 | if (iMax == -1)
201 | return "[]";
202 |
203 | StringBuilder b = new StringBuilder();
204 | b.append('[');
205 | for (int i = 0; ; i++) {
206 | b.append(getRaw(byteOffset(i)));
207 | if (i == iMax)
208 | return b.append(']').toString();
209 | b.append(',').append(' ');
210 | }
211 | }
212 |
213 | }
214 |
--------------------------------------------------------------------------------
/TheArtOFMultiprocessorProgramming/concurrent/atomic/AtomicInteger.java:
--------------------------------------------------------------------------------
1 | /*
2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3 | *
4 | * This code is free software; you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License version 2 only, as
6 | * published by the Free Software Foundation. Oracle designates this
7 | * particular file as subject to the "Classpath" exception as provided
8 | * by Oracle in the LICENSE file that accompanied this code.
9 | *
10 | * This code is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 | * version 2 for more details (a copy is included in the LICENSE file that
14 | * accompanied this code).
15 | *
16 | * You should have received a copy of the GNU General Public License version
17 | * 2 along with this work; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 | *
20 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 | * or visit www.oracle.com if you need additional information or have any
22 | * questions.
23 | */
24 |
25 | /*
26 | * This file is available under and governed by the GNU General Public
27 | * License version 2 only, as published by the Free Software Foundation.
28 | * However, the following notice accompanied the original version of this
29 | * file:
30 | *
31 | * Written by Doug Lea with assistance from members of JCP JSR-166
32 | * Expert Group and released to the public domain, as explained at
33 | * http://creativecommons.org/publicdomain/zero/1.0/
34 | */
35 |
36 | package java.util.concurrent.atomic;
37 | import sun.misc.Unsafe;
38 |
39 | /**
40 | * An {@code int} value that may be updated atomically. See the
41 | * {@link java.util.concurrent.atomic} package specification for
42 | * description of the properties of atomic variables. An
43 | * {@code AtomicInteger} is used in applications such as atomically
44 | * incremented counters, and cannot be used as a replacement for an
45 | * {@link java.lang.Integer}. However, this class does extend
46 | * {@code Number} to allow uniform access by tools and utilities that
47 | * deal with numerically-based classes.
48 | *
49 | * @since 1.5
50 | * @author Doug Lea
51 | */
52 | public class AtomicInteger extends Number implements java.io.Serializable {
53 | private static final long serialVersionUID = 6214790243416807050L;
54 |
55 | // setup to use Unsafe.compareAndSwapInt for updates
56 | private static final Unsafe unsafe = Unsafe.getUnsafe();
57 | private static final long valueOffset;
58 |
59 | static {
60 | try {
61 | valueOffset = unsafe.objectFieldOffset
62 | (AtomicInteger.class.getDeclaredField("value"));
63 | } catch (Exception ex) { throw new Error(ex); }
64 | }
65 |
66 | private volatile int value;
67 |
68 | /**
69 | * Creates a new AtomicInteger with the given initial value.
70 | *
71 | * @param initialValue the initial value
72 | */
73 | public AtomicInteger(int initialValue) {
74 | value = initialValue;
75 | }
76 |
77 | /**
78 | * Creates a new AtomicInteger with initial value {@code 0}.
79 | */
80 | public AtomicInteger() {
81 | }
82 |
83 | /**
84 | * Gets the current value.
85 | *
86 | * @return the current value
87 | */
88 | public final int get() {
89 | return value;
90 | }
91 |
92 | /**
93 | * Sets to the given value.
94 | *
95 | * @param newValue the new value
96 | */
97 | public final void set(int newValue) {
98 | value = newValue;
99 | }
100 |
101 | /**
102 | * Eventually sets to the given value.
103 | *
104 | * @param newValue the new value
105 | * @since 1.6
106 | */
107 | public final void lazySet(int newValue) {
108 | unsafe.putOrderedInt(this, valueOffset, newValue);
109 | }
110 |
111 | /**
112 | * Atomically sets to the given value and returns the old value.
113 | *
114 | * @param newValue the new value
115 | * @return the previous value
116 | */
117 | public final int getAndSet(int newValue) {
118 | for (;;) {
119 | int current = get();
120 | if (compareAndSet(current, newValue))
121 | return current;
122 | }
123 | }
124 |
125 | /**
126 | * Atomically sets the value to the given updated value
127 | * if the current value {@code ==} the expected value.
128 | *
129 | * @param expect the expected value
130 | * @param update the new value
131 | * @return true if successful. False return indicates that
132 | * the actual value was not equal to the expected value.
133 | */
134 | public final boolean compareAndSet(int expect, int update) {
135 | return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
136 | }
137 |
138 | /**
139 | * Atomically sets the value to the given updated value
140 | * if the current value {@code ==} the expected value.
141 | *
142 | * May fail spuriously
143 | * and does not provide ordering guarantees, so is only rarely an
144 | * appropriate alternative to {@code compareAndSet}.
145 | *
146 | * @param expect the expected value
147 | * @param update the new value
148 | * @return true if successful.
149 | */
150 | public final boolean weakCompareAndSet(int expect, int update) {
151 | return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
152 | }
153 |
154 | /**
155 | * Atomically increments by one the current value.
156 | *
157 | * @return the previous value
158 | */
159 | public final int getAndIncrement() {
160 | for (;;) {
161 | int current = get();
162 | int next = current + 1;
163 | if (compareAndSet(current, next))
164 | return current;
165 | }
166 | }
167 |
168 | /**
169 | * Atomically decrements by one the current value.
170 | *
171 | * @return the previous value
172 | */
173 | public final int getAndDecrement() {
174 | for (;;) {
175 | int current = get();
176 | int next = current - 1;
177 | if (compareAndSet(current, next))
178 | return current;
179 | }
180 | }
181 |
182 | /**
183 | * Atomically adds the given value to the current value.
184 | *
185 | * @param delta the value to add
186 | * @return the previous value
187 | */
188 | public final int getAndAdd(int delta) {
189 | for (;;) {
190 | int current = get();
191 | int next = current + delta;
192 | if (compareAndSet(current, next))
193 | return current;
194 | }
195 | }
196 |
197 | /**
198 | * Atomically increments by one the current value.
199 | *
200 | * @return the updated value
201 | */
202 | public final int incrementAndGet() {
203 | for (;;) {
204 | int current = get();
205 | int next = current + 1;
206 | if (compareAndSet(current, next))
207 | return next;
208 | }
209 | }
210 |
211 | /**
212 | * Atomically decrements by one the current value.
213 | *
214 | * @return the updated value
215 | */
216 | public final int decrementAndGet() {
217 | for (;;) {
218 | int current = get();
219 | int next = current - 1;
220 | if (compareAndSet(current, next))
221 | return next;
222 | }
223 | }
224 |
225 | /**
226 | * Atomically adds the given value to the current value.
227 | *
228 | * @param delta the value to add
229 | * @return the updated value
230 | */
231 | public final int addAndGet(int delta) {
232 | for (;;) {
233 | int current = get();
234 | int next = current + delta;
235 | if (compareAndSet(current, next))
236 | return next;
237 | }
238 | }
239 |
240 | /**
241 | * Returns the String representation of the current value.
242 | * @return the String representation of the current value.
243 | */
244 | public String toString() {
245 | return Integer.toString(get());
246 | }
247 |
248 |
249 | public int intValue() {
250 | return get();
251 | }
252 |
253 | public long longValue() {
254 | return (long)get();
255 | }
256 |
257 | public float floatValue() {
258 | return (float)get();
259 | }
260 |
261 | public double doubleValue() {
262 | return (double)get();
263 | }
264 |
265 | }
266 |
--------------------------------------------------------------------------------
/TheArtOFMultiprocessorProgramming/concurrent/atomic/AtomicStampedReference.java:
--------------------------------------------------------------------------------
1 | /*
2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3 | *
4 | * This code is free software; you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License version 2 only, as
6 | * published by the Free Software Foundation. Oracle designates this
7 | * particular file as subject to the "Classpath" exception as provided
8 | * by Oracle in the LICENSE file that accompanied this code.
9 | *
10 | * This code is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 | * version 2 for more details (a copy is included in the LICENSE file that
14 | * accompanied this code).
15 | *
16 | * You should have received a copy of the GNU General Public License version
17 | * 2 along with this work; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 | *
20 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 | * or visit www.oracle.com if you need additional information or have any
22 | * questions.
23 | */
24 |
25 | /*
26 | * This file is available under and governed by the GNU General Public
27 | * License version 2 only, as published by the Free Software Foundation.
28 | * However, the following notice accompanied the original version of this
29 | * file:
30 | *
31 | * Written by Doug Lea with assistance from members of JCP JSR-166
32 | * Expert Group and released to the public domain, as explained at
33 | * http://creativecommons.org/publicdomain/zero/1.0/
34 | */
35 |
36 | package java.util.concurrent.atomic;
37 |
38 | /**
39 | * An {@code AtomicStampedReference} maintains an object reference
40 | * along with an integer "stamp", that can be updated atomically.
41 | *
42 | * Implementation note: This implementation maintains stamped
43 | * references by creating internal objects representing "boxed"
44 | * [reference, integer] pairs.
45 | *
46 | * @since 1.5
47 | * @author Doug Lea
48 | * @param May fail spuriously
117 | * and does not provide ordering guarantees, so is only rarely an
118 | * appropriate alternative to {@code compareAndSet}.
119 | *
120 | * @param expectedReference the expected value of the reference
121 | * @param newReference the new value for the reference
122 | * @param expectedStamp the expected value of the stamp
123 | * @param newStamp the new value for the stamp
124 | * @return true if successful
125 | */
126 | public boolean weakCompareAndSet(V expectedReference,
127 | V newReference,
128 | int expectedStamp,
129 | int newStamp) {
130 | return compareAndSet(expectedReference, newReference,
131 | expectedStamp, newStamp);
132 | }
133 |
134 | /**
135 | * Atomically sets the value of both the reference and stamp
136 | * to the given update values if the
137 | * current reference is {@code ==} to the expected reference
138 | * and the current stamp is equal to the expected stamp.
139 | *
140 | * @param expectedReference the expected value of the reference
141 | * @param newReference the new value for the reference
142 | * @param expectedStamp the expected value of the stamp
143 | * @param newStamp the new value for the stamp
144 | * @return true if successful
145 | */
146 | public boolean compareAndSet(V expectedReference,
147 | V newReference,
148 | int expectedStamp,
149 | int newStamp) {
150 | Pair Implementation note: This implementation maintains markable
43 | * references by creating internal objects representing "boxed"
44 | * [reference, boolean] pairs.
45 | *
46 | * @since 1.5
47 | * @author Doug Lea
48 | * @param May fail spuriously
118 | * and does not provide ordering guarantees, so is only rarely an
119 | * appropriate alternative to {@code compareAndSet}.
120 | *
121 | * @param expectedReference the expected value of the reference
122 | * @param newReference the new value for the reference
123 | * @param expectedMark the expected value of the mark
124 | * @param newMark the new value for the mark
125 | * @return true if successful
126 | */
127 | public boolean weakCompareAndSet(V expectedReference,
128 | V newReference,
129 | boolean expectedMark,
130 | boolean newMark) {
131 | return compareAndSet(expectedReference, newReference,
132 | expectedMark, newMark);
133 | }
134 |
135 | /**
136 | * Atomically sets the value of both the reference and mark
137 | * to the given update values if the
138 | * current reference is {@code ==} to the expected reference
139 | * and the current mark is equal to the expected mark.
140 | *
141 | * @param expectedReference the expected value of the reference
142 | * @param newReference the new value for the reference
143 | * @param expectedMark the expected value of the mark
144 | * @param newMark the new value for the mark
145 | * @return true if successful
146 | */
147 | public boolean compareAndSet(V expectedReference,
148 | V newReference,
149 | boolean expectedMark,
150 | boolean newMark) {
151 | //缓存了一份pair
152 | Pair May fail spuriously
157 | * and does not provide ordering guarantees, so is only rarely an
158 | * appropriate alternative to {@code compareAndSet}.
159 | *
160 | * @param expect the expected value
161 | * @param update the new value
162 | * @return true if successful.
163 | */
164 | public final boolean weakCompareAndSet(long expect, long update) {
165 | return unsafe.compareAndSwapLong(this, valueOffset, expect, update);
166 | }
167 |
168 | /**
169 | * Atomically increments by one the current value.
170 | *
171 | * @return the previous value
172 | */
173 | public final long getAndIncrement() {
174 | while (true) {
175 | long current = get();
176 | long next = current + 1;
177 | if (compareAndSet(current, next))
178 | return current;
179 | }
180 | }
181 |
182 | /**
183 | * Atomically decrements by one the current value.
184 | *
185 | * @return the previous value
186 | */
187 | public final long getAndDecrement() {
188 | while (true) {
189 | long current = get();
190 | long next = current - 1;
191 | if (compareAndSet(current, next))
192 | return current;
193 | }
194 | }
195 |
196 | /**
197 | * Atomically adds the given value to the current value.
198 | *
199 | * @param delta the value to add
200 | * @return the previous value
201 | */
202 | public final long getAndAdd(long delta) {
203 | while (true) {
204 | long current = get();
205 | long next = current + delta;
206 | if (compareAndSet(current, next))
207 | return current;
208 | }
209 | }
210 |
211 | /**
212 | * Atomically increments by one the current value.
213 | *
214 | * @return the updated value
215 | */
216 | public final long incrementAndGet() {
217 | for (;;) {
218 | long current = get();
219 | long next = current + 1;
220 | if (compareAndSet(current, next))
221 | return next;
222 | }
223 | }
224 |
225 | /**
226 | * Atomically decrements by one the current value.
227 | *
228 | * @return the updated value
229 | */
230 | public final long decrementAndGet() {
231 | for (;;) {
232 | long current = get();
233 | long next = current - 1;
234 | if (compareAndSet(current, next))
235 | return next;
236 | }
237 | }
238 |
239 | /**
240 | * Atomically adds the given value to the current value.
241 | *
242 | * @param delta the value to add
243 | * @return the updated value
244 | */
245 | public final long addAndGet(long delta) {
246 | for (;;) {
247 | long current = get();
248 | long next = current + delta;
249 | if (compareAndSet(current, next))
250 | return next;
251 | }
252 | }
253 |
254 | /**
255 | * Returns the String representation of the current value.
256 | * @return the String representation of the current value.
257 | */
258 | public String toString() {
259 | return Long.toString(get());
260 | }
261 |
262 |
263 | public int intValue() {
264 | return (int)get();
265 | }
266 |
267 | public long longValue() {
268 | return get();
269 | }
270 |
271 | public float floatValue() {
272 | return (float)get();
273 | }
274 |
275 | public double doubleValue() {
276 | return (double)get();
277 | }
278 |
279 | }
280 |
--------------------------------------------------------------------------------
/TheArtOFMultiprocessorProgramming/park.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software; you can redistribute it and/or modify it
6 | * under the terms of the GNU General Public License version 2 only, as
7 | * published by the Free Software Foundation.
8 | *
9 | * This code is distributed in the hope that it will be useful, but WITHOUT
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 | * version 2 for more details (a copy is included in the LICENSE file that
13 | * accompanied this code).
14 | *
15 | * You should have received a copy of the GNU General Public License version
16 | * 2 along with this work; if not, write to the Free Software Foundation,
17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 | *
19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 | * or visit www.oracle.com if you need additional information or have any
21 | * questions.
22 | *
23 | */
24 |
25 | #include "precompiled.hpp"
26 | #include "runtime/thread.hpp"
27 |
28 |
29 |
30 | // Lifecycle management for TSM ParkEvents.
31 | // ParkEvents are type-stable (TSM).
32 | // In our particular implementation they happen to be immortal.
33 | //
34 | // We manage concurrency on the FreeList with a CAS-based
35 | // detach-modify-reattach idiom that avoids the ABA problems
36 | // that would otherwise be present in a simple CAS-based
37 | // push-pop implementation. (push-one and pop-all)
38 | //
39 | // Caveat: Allocate() and Release() may be called from threads
40 | // other than the thread associated with the Event!
41 | // If we need to call Allocate() when running as the thread in
42 | // question then look for the PD calls to initialize native TLS.
43 | // Native TLS (Win32/Linux/Solaris) can only be initialized or
44 | // accessed by the associated thread.
45 | // See also pd_initialize().
46 | //
47 | // Note that we could defer associating a ParkEvent with a thread
48 | // until the 1st time the thread calls park(). unpark() calls to
49 | // an unprovisioned thread would be ignored. The first park() call
50 | // for a thread would allocate and associate a ParkEvent and return
51 | // immediately.
52 |
53 | volatile int ParkEvent::ListLock = 0 ;
54 | ParkEvent * volatile ParkEvent::FreeList = NULL ;
55 |
56 | ParkEvent * ParkEvent::Allocate (Thread * t) {
57 | // In rare cases -- JVM_RawMonitor* operations -- we can find t == null.
58 | ParkEvent * ev ;
59 |
60 | // Start by trying to recycle an existing but unassociated
61 | // ParkEvent from the global free list.
62 | for (;;) {
63 | ev = FreeList ;
64 | if (ev == NULL) break ;
65 | // 1: Detach - sequester or privatize the list
66 | // Tantamount to ev = Swap (&FreeList, NULL)
67 | if (Atomic::cmpxchg_ptr (NULL, &FreeList, ev) != ev) {
68 | continue ;
69 | }
70 |
71 | // We've detached the list. The list in-hand is now
72 | // local to this thread. This thread can operate on the
73 | // list without risk of interference from other threads.
74 | // 2: Extract -- pop the 1st element from the list.
75 | ParkEvent * List = ev->FreeNext ;
76 | if (List == NULL) break ;
77 | for (;;) {
78 | // 3: Try to reattach the residual list
79 | guarantee (List != NULL, "invariant") ;
80 | ParkEvent * Arv = (ParkEvent *) Atomic::cmpxchg_ptr (List, &FreeList, NULL) ;
81 | if (Arv == NULL) break ;
82 |
83 | // New nodes arrived. Try to detach the recent arrivals.
84 | if (Atomic::cmpxchg_ptr (NULL, &FreeList, Arv) != Arv) {
85 | continue ;
86 | }
87 | guarantee (Arv != NULL, "invariant") ;
88 | // 4: Merge Arv into List
89 | ParkEvent * Tail = List ;
90 | while (Tail->FreeNext != NULL) Tail = Tail->FreeNext ;
91 | Tail->FreeNext = Arv ;
92 | }
93 | break ;
94 | }
95 |
96 | if (ev != NULL) {
97 | guarantee (ev->AssociatedWith == NULL, "invariant") ;
98 | } else {
99 | // Do this the hard way -- materialize a new ParkEvent.
100 | // In rare cases an allocating thread might detach a long list --
101 | // installing null into FreeList -- and then stall or be obstructed.
102 | // A 2nd thread calling Allocate() would see FreeList == null.
103 | // The list held privately by the 1st thread is unavailable to the 2nd thread.
104 | // In that case the 2nd thread would have to materialize a new ParkEvent,
105 | // even though free ParkEvents existed in the system. In this case we end up
106 | // with more ParkEvents in circulation than we need, but the race is
107 | // rare and the outcome is benign. Ideally, the # of extant ParkEvents
108 | // is equal to the maximum # of threads that existed at any one time.
109 | // Because of the race mentioned above, segments of the freelist
110 | // can be transiently inaccessible. At worst we may end up with the
111 | // # of ParkEvents in circulation slightly above the ideal.
112 | // Note that if we didn't have the TSM/immortal constraint, then
113 | // when reattaching, above, we could trim the list.
114 | ev = new ParkEvent () ;
115 | guarantee ((intptr_t(ev) & 0xFF) == 0, "invariant") ;
116 | }
117 | ev->reset() ; // courtesy to caller
118 | ev->AssociatedWith = t ; // Associate ev with t
119 | ev->FreeNext = NULL ;
120 | return ev ;
121 | }
122 |
123 | void ParkEvent::Release (ParkEvent * ev) {
124 | if (ev == NULL) return ;
125 | guarantee (ev->FreeNext == NULL , "invariant") ;
126 | ev->AssociatedWith = NULL ;
127 | for (;;) {
128 | // Push ev onto FreeList
129 | // The mechanism is "half" lock-free.
130 | ParkEvent * List = FreeList ;
131 | ev->FreeNext = List ;
132 | if (Atomic::cmpxchg_ptr (ev, &FreeList, List) == List) break ;
133 | }
134 | }
135 |
136 | // Override operator new and delete so we can ensure that the
137 | // least significant byte of ParkEvent addresses is 0.
138 | // Beware that excessive address alignment is undesirable
139 | // as it can result in D$ index usage imbalance as
140 | // well as bank access imbalance on Niagara-like platforms,
141 | // although Niagara's hash function should help.
142 |
143 | void * ParkEvent::operator new (size_t sz) {
144 | return (void *) ((intptr_t (CHeapObj::operator new (sz + 256)) + 256) & -256) ;
145 | }
146 |
147 | void ParkEvent::operator delete (void * a) {
148 | // ParkEvents are type-stable and immortal ...
149 | ShouldNotReachHere();
150 | }
151 |
152 |
153 | // 6399321 As a temporary measure we copied & modified the ParkEvent::
154 | // allocate() and release() code for use by Parkers. The Parker:: forms
155 | // will eventually be removed as we consolide and shift over to ParkEvents
156 | // for both builtin synchronization and JSR166 operations.
157 |
158 | volatile int Parker::ListLock = 0 ;
159 | Parker * volatile Parker::FreeList = NULL ;
160 |
161 | Parker * Parker::Allocate (JavaThread * t) {
162 | guarantee (t != NULL, "invariant") ;
163 | Parker * p ;
164 |
165 | // Start by trying to recycle an existing but unassociated
166 | // Parker from the global free list.
167 | for (;;) {
168 | p = FreeList ;
169 | if (p == NULL) break ;
170 | // 1: Detach
171 | // Tantamount to p = Swap (&FreeList, NULL)
172 | if (Atomic::cmpxchg_ptr (NULL, &FreeList, p) != p) {
173 | continue ;
174 | }
175 |
176 | // We've detached the list. The list in-hand is now
177 | // local to this thread. This thread can operate on the
178 | // list without risk of interference from other threads.
179 | // 2: Extract -- pop the 1st element from the list.
180 | Parker * List = p->FreeNext ;
181 | if (List == NULL) break ;
182 | for (;;) {
183 | // 3: Try to reattach the residual list
184 | guarantee (List != NULL, "invariant") ;
185 | Parker * Arv = (Parker *) Atomic::cmpxchg_ptr (List, &FreeList, NULL) ;
186 | if (Arv == NULL) break ;
187 |
188 | // New nodes arrived. Try to detach the recent arrivals.
189 | if (Atomic::cmpxchg_ptr (NULL, &FreeList, Arv) != Arv) {
190 | continue ;
191 | }
192 | guarantee (Arv != NULL, "invariant") ;
193 | // 4: Merge Arv into List
194 | Parker * Tail = List ;
195 | while (Tail->FreeNext != NULL) Tail = Tail->FreeNext ;
196 | Tail->FreeNext = Arv ;
197 | }
198 | break ;
199 | }
200 |
201 | if (p != NULL) {
202 | guarantee (p->AssociatedWith == NULL, "invariant") ;
203 | } else {
204 | // Do this the hard way -- materialize a new Parker..
205 | // In rare cases an allocating thread might detach
206 | // a long list -- installing null into FreeList --and
207 | // then stall. Another thread calling Allocate() would see
208 | // FreeList == null and then invoke the ctor. In this case we
209 | // end up with more Parkers in circulation than we need, but
210 | // the race is rare and the outcome is benign.
211 | // Ideally, the # of extant Parkers is equal to the
212 | // maximum # of threads that existed at any one time.
213 | // Because of the race mentioned above, segments of the
214 | // freelist can be transiently inaccessible. At worst
215 | // we may end up with the # of Parkers in circulation
216 | // slightly above the ideal.
217 | p = new Parker() ;
218 | }
219 | p->AssociatedWith = t ; // Associate p with t
220 | p->FreeNext = NULL ;
221 | return p ;
222 | }
223 |
224 |
225 | void Parker::Release (Parker * p) {
226 | if (p == NULL) return ;
227 | guarantee (p->AssociatedWith != NULL, "invariant") ;
228 | guarantee (p->FreeNext == NULL , "invariant") ;
229 | p->AssociatedWith = NULL ;
230 | for (;;) {
231 | // Push p onto FreeList
232 | Parker * List = FreeList ;
233 | p->FreeNext = List ;
234 | if (Atomic::cmpxchg_ptr (p, &FreeList, List) == List) break ;
235 | }
236 | }
237 |
238 |
--------------------------------------------------------------------------------
/TheArtOFMultiprocessorProgramming/concurrent/atomic/AtomicLongArray.java:
--------------------------------------------------------------------------------
1 | /*
2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3 | *
4 | * This code is free software; you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License version 2 only, as
6 | * published by the Free Software Foundation. Oracle designates this
7 | * particular file as subject to the "Classpath" exception as provided
8 | * by Oracle in the LICENSE file that accompanied this code.
9 | *
10 | * This code is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 | * version 2 for more details (a copy is included in the LICENSE file that
14 | * accompanied this code).
15 | *
16 | * You should have received a copy of the GNU General Public License version
17 | * 2 along with this work; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 | *
20 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 | * or visit www.oracle.com if you need additional information or have any
22 | * questions.
23 | */
24 |
25 | /*
26 | * This file is available under and governed by the GNU General Public
27 | * License version 2 only, as published by the Free Software Foundation.
28 | * However, the following notice accompanied the original version of this
29 | * file:
30 | *
31 | * Written by Doug Lea with assistance from members of JCP JSR-166
32 | * Expert Group and released to the public domain, as explained at
33 | * http://creativecommons.org/publicdomain/zero/1.0/
34 | */
35 |
36 | package java.util.concurrent.atomic;
37 | import sun.misc.Unsafe;
38 | import java.util.*;
39 |
40 | /**
41 | * A {@code long} array in which elements may be updated atomically.
42 | * See the {@link java.util.concurrent.atomic} package specification
43 | * for description of the properties of atomic variables.
44 | * @since 1.5
45 | * @author Doug Lea
46 | */
47 | public class AtomicLongArray implements java.io.Serializable {
48 | private static final long serialVersionUID = -2308431214976778248L;
49 |
50 | private static final Unsafe unsafe = Unsafe.getUnsafe();
51 | private static final int base = unsafe.arrayBaseOffset(long[].class);
52 | private static final int shift;
53 | private final long[] array;
54 |
55 | static {
56 | int scale = unsafe.arrayIndexScale(long[].class);
57 | if ((scale & (scale - 1)) != 0)
58 | throw new Error("data type scale not a power of two");
59 | shift = 31 - Integer.numberOfLeadingZeros(scale);
60 | }
61 |
62 | private long checkedByteOffset(int i) {
63 | if (i < 0 || i >= array.length)
64 | throw new IndexOutOfBoundsException("index " + i);
65 |
66 | return byteOffset(i);
67 | }
68 |
69 | private static long byteOffset(int i) {
70 | return ((long) i << shift) + base;
71 | }
72 |
73 | /**
74 | * Creates a new AtomicLongArray of the given length, with all
75 | * elements initially zero.
76 | *
77 | * @param length the length of the array
78 | */
79 | public AtomicLongArray(int length) {
80 | array = new long[length];
81 | }
82 |
83 | /**
84 | * Creates a new AtomicLongArray with the same length as, and
85 | * all elements copied from, the given array.
86 | *
87 | * @param array the array to copy elements from
88 | * @throws NullPointerException if array is null
89 | */
90 | public AtomicLongArray(long[] array) {
91 | // Visibility guaranteed by final field guarantees
92 | this.array = array.clone();
93 | }
94 |
95 | /**
96 | * Returns the length of the array.
97 | *
98 | * @return the length of the array
99 | */
100 | public final int length() {
101 | return array.length;
102 | }
103 |
104 | /**
105 | * Gets the current value at position {@code i}.
106 | *
107 | * @param i the index
108 | * @return the current value
109 | */
110 | public final long get(int i) {
111 | return getRaw(checkedByteOffset(i));
112 | }
113 |
114 | private long getRaw(long offset) {
115 | return unsafe.getLongVolatile(array, offset);
116 | }
117 |
118 | /**
119 | * Sets the element at position {@code i} to the given value.
120 | *
121 | * @param i the index
122 | * @param newValue the new value
123 | */
124 | public final void set(int i, long newValue) {
125 | unsafe.putLongVolatile(array, checkedByteOffset(i), newValue);
126 | }
127 |
128 | /**
129 | * Eventually sets the element at position {@code i} to the given value.
130 | *
131 | * @param i the index
132 | * @param newValue the new value
133 | * @since 1.6
134 | */
135 | public final void lazySet(int i, long newValue) {
136 | unsafe.putOrderedLong(array, checkedByteOffset(i), newValue);
137 | }
138 |
139 |
140 | /**
141 | * Atomically sets the element at position {@code i} to the given value
142 | * and returns the old value.
143 | *
144 | * @param i the index
145 | * @param newValue the new value
146 | * @return the previous value
147 | */
148 | public final long getAndSet(int i, long newValue) {
149 | long offset = checkedByteOffset(i);
150 | while (true) {
151 | long current = getRaw(offset);
152 | if (compareAndSetRaw(offset, current, newValue))
153 | return current;
154 | }
155 | }
156 |
157 | /**
158 | * Atomically sets the element at position {@code i} to the given
159 | * updated value if the current value {@code ==} the expected value.
160 | *
161 | * @param i the index
162 | * @param expect the expected value
163 | * @param update the new value
164 | * @return true if successful. False return indicates that
165 | * the actual value was not equal to the expected value.
166 | */
167 | public final boolean compareAndSet(int i, long expect, long update) {
168 | return compareAndSetRaw(checkedByteOffset(i), expect, update);
169 | }
170 |
171 | private boolean compareAndSetRaw(long offset, long expect, long update) {
172 | return unsafe.compareAndSwapLong(array, offset, expect, update);
173 | }
174 |
175 | /**
176 | * Atomically sets the element at position {@code i} to the given
177 | * updated value if the current value {@code ==} the expected value.
178 | *
179 | * May fail spuriously
180 | * and does not provide ordering guarantees, so is only rarely an
181 | * appropriate alternative to {@code compareAndSet}.
182 | *
183 | * @param i the index
184 | * @param expect the expected value
185 | * @param update the new value
186 | * @return true if successful.
187 | */
188 | public final boolean weakCompareAndSet(int i, long expect, long update) {
189 | return compareAndSet(i, expect, update);
190 | }
191 |
192 | /**
193 | * Atomically increments by one the element at index {@code i}.
194 | *
195 | * @param i the index
196 | * @return the previous value
197 | */
198 | public final long getAndIncrement(int i) {
199 | return getAndAdd(i, 1);
200 | }
201 |
202 | /**
203 | * Atomically decrements by one the element at index {@code i}.
204 | *
205 | * @param i the index
206 | * @return the previous value
207 | */
208 | public final long getAndDecrement(int i) {
209 | return getAndAdd(i, -1);
210 | }
211 |
212 | /**
213 | * Atomically adds the given value to the element at index {@code i}.
214 | *
215 | * @param i the index
216 | * @param delta the value to add
217 | * @return the previous value
218 | */
219 | public final long getAndAdd(int i, long delta) {
220 | long offset = checkedByteOffset(i);
221 | while (true) {
222 | long current = getRaw(offset);
223 | if (compareAndSetRaw(offset, current, current + delta))
224 | return current;
225 | }
226 | }
227 |
228 | /**
229 | * Atomically increments by one the element at index {@code i}.
230 | *
231 | * @param i the index
232 | * @return the updated value
233 | */
234 | public final long incrementAndGet(int i) {
235 | return addAndGet(i, 1);
236 | }
237 |
238 | /**
239 | * Atomically decrements by one the element at index {@code i}.
240 | *
241 | * @param i the index
242 | * @return the updated value
243 | */
244 | public final long decrementAndGet(int i) {
245 | return addAndGet(i, -1);
246 | }
247 |
248 | /**
249 | * Atomically adds the given value to the element at index {@code i}.
250 | *
251 | * @param i the index
252 | * @param delta the value to add
253 | * @return the updated value
254 | */
255 | public long addAndGet(int i, long delta) {
256 | long offset = checkedByteOffset(i);
257 | while (true) {
258 | long current = getRaw(offset);
259 | long next = current + delta;
260 | if (compareAndSetRaw(offset, current, next))
261 | return next;
262 | }
263 | }
264 |
265 | /**
266 | * Returns the String representation of the current values of array.
267 | * @return the String representation of the current values of array
268 | */
269 | public String toString() {
270 | int iMax = array.length - 1;
271 | if (iMax == -1)
272 | return "[]";
273 |
274 | StringBuilder b = new StringBuilder();
275 | b.append('[');
276 | for (int i = 0; ; i++) {
277 | b.append(getRaw(byteOffset(i)));
278 | if (i == iMax)
279 | return b.append(']').toString();
280 | b.append(',').append(' ');
281 | }
282 | }
283 |
284 | }
285 |
--------------------------------------------------------------------------------
/TheArtOFMultiprocessorProgramming/concurrent/atomic/AtomicIntegerArray.java:
--------------------------------------------------------------------------------
1 | /*
2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3 | *
4 | * This code is free software; you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License version 2 only, as
6 | * published by the Free Software Foundation. Oracle designates this
7 | * particular file as subject to the "Classpath" exception as provided
8 | * by Oracle in the LICENSE file that accompanied this code.
9 | *
10 | * This code is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 | * version 2 for more details (a copy is included in the LICENSE file that
14 | * accompanied this code).
15 | *
16 | * You should have received a copy of the GNU General Public License version
17 | * 2 along with this work; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 | *
20 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 | * or visit www.oracle.com if you need additional information or have any
22 | * questions.
23 | */
24 |
25 | /*
26 | * This file is available under and governed by the GNU General Public
27 | * License version 2 only, as published by the Free Software Foundation.
28 | * However, the following notice accompanied the original version of this
29 | * file:
30 | *
31 | * Written by Doug Lea with assistance from members of JCP JSR-166
32 | * Expert Group and released to the public domain, as explained at
33 | * http://creativecommons.org/publicdomain/zero/1.0/
34 | */
35 |
36 | package java.util.concurrent.atomic;
37 | import sun.misc.Unsafe;
38 | import java.util.*;
39 |
40 | /**
41 | * An {@code int} array in which elements may be updated atomically.
42 | * See the {@link java.util.concurrent.atomic} package
43 | * specification for description of the properties of atomic
44 | * variables.
45 | * @since 1.5
46 | * @author Doug Lea
47 | */
48 | public class AtomicIntegerArray implements java.io.Serializable {
49 | private static final long serialVersionUID = 2862133569453604235L;
50 |
51 | private static final Unsafe unsafe = Unsafe.getUnsafe();
52 | private static final int base = unsafe.arrayBaseOffset(int[].class);
53 | private static final int shift;
54 | private final int[] array;
55 |
56 | static {
57 | int scale = unsafe.arrayIndexScale(int[].class);
58 | if ((scale & (scale - 1)) != 0)
59 | throw new Error("data type scale not a power of two");
60 | //Integer.numberOfLeadingZeros返回数据的二进制串中从最左边算起连续的“0”的总数量。
61 | shift = 31 - Integer.numberOfLeadingZeros(scale);
62 | }
63 |
64 | private long checkedByteOffset(int i) {
65 | if (i < 0 || i >= array.length)
66 | throw new IndexOutOfBoundsException("index " + i);
67 |
68 | return byteOffset(i);
69 | }
70 |
71 | private static long byteOffset(int i) {
72 | return ((long) i << shift) + base;
73 | }
74 |
75 | /**
76 | * Creates a new AtomicIntegerArray of the given length, with all
77 | * elements initially zero.
78 | *
79 | * @param length the length of the array
80 | */
81 | public AtomicIntegerArray(int length) {
82 | array = new int[length];
83 | }
84 |
85 | /**
86 | * Creates a new AtomicIntegerArray with the same length as, and
87 | * all elements copied from, the given array.
88 | *
89 | * @param array the array to copy elements from
90 | * @throws NullPointerException if array is null
91 | */
92 | public AtomicIntegerArray(int[] array) {
93 | // Visibility guaranteed by final field guarantees
94 | this.array = array.clone();
95 | }
96 |
97 | /**
98 | * Returns the length of the array.
99 | *
100 | * @return the length of the array
101 | */
102 | public final int length() {
103 | return array.length;
104 | }
105 |
106 | /**
107 | * Gets the current value at position {@code i}.
108 | *
109 | * @param i the index
110 | * @return the current value
111 | */
112 | public final int get(int i) {
113 | return getRaw(checkedByteOffset(i));
114 | }
115 |
116 | private int getRaw(long offset) {
117 | return unsafe.getIntVolatile(array, offset);
118 | }
119 |
120 | /**
121 | * Sets the element at position {@code i} to the given value.
122 | *
123 | * @param i the index
124 | * @param newValue the new value
125 | */
126 | public final void set(int i, int newValue) {
127 | unsafe.putIntVolatile(array, checkedByteOffset(i), newValue);
128 | }
129 |
130 | /**
131 | * Eventually sets the element at position {@code i} to the given value.
132 | *
133 | * @param i the index
134 | * @param newValue the new value
135 | * @since 1.6
136 | */
137 | public final void lazySet(int i, int newValue) {
138 | unsafe.putOrderedInt(array, checkedByteOffset(i), newValue);
139 | }
140 |
141 | /**
142 | * Atomically sets the element at position {@code i} to the given
143 | * value and returns the old value.
144 | *
145 | * @param i the index
146 | * @param newValue the new value
147 | * @return the previous value
148 | */
149 | public final int getAndSet(int i, int newValue) {
150 | long offset = checkedByteOffset(i);
151 | while (true) {
152 | int current = getRaw(offset);
153 | if (compareAndSetRaw(offset, current, newValue))
154 | return current;
155 | }
156 | }
157 |
158 | /**
159 | * Atomically sets the element at position {@code i} to the given
160 | * updated value if the current value {@code ==} the expected value.
161 | *
162 | * @param i the index
163 | * @param expect the expected value
164 | * @param update the new value
165 | * @return true if successful. False return indicates that
166 | * the actual value was not equal to the expected value.
167 | */
168 | public final boolean compareAndSet(int i, int expect, int update) {
169 | return compareAndSetRaw(checkedByteOffset(i), expect, update);
170 | }
171 |
172 | private boolean compareAndSetRaw(long offset, int expect, int update) {
173 | return unsafe.compareAndSwapInt(array, offset, expect, update);
174 | }
175 |
176 | /**
177 | * Atomically sets the element at position {@code i} to the given
178 | * updated value if the current value {@code ==} the expected value.
179 | *
180 | * May fail spuriously
181 | * and does not provide ordering guarantees, so is only rarely an
182 | * appropriate alternative to {@code compareAndSet}.
183 | *
184 | * @param i the index
185 | * @param expect the expected value
186 | * @param update the new value
187 | * @return true if successful.
188 | */
189 | public final boolean weakCompareAndSet(int i, int expect, int update) {
190 | return compareAndSet(i, expect, update);
191 | }
192 |
193 | /**
194 | * Atomically increments by one the element at index {@code i}.
195 | *
196 | * @param i the index
197 | * @return the previous value
198 | */
199 | public final int getAndIncrement(int i) {
200 | return getAndAdd(i, 1);
201 | }
202 |
203 | /**
204 | * Atomically decrements by one the element at index {@code i}.
205 | *
206 | * @param i the index
207 | * @return the previous value
208 | */
209 | public final int getAndDecrement(int i) {
210 | return getAndAdd(i, -1);
211 | }
212 |
213 | /**
214 | * Atomically adds the given value to the element at index {@code i}.
215 | *
216 | * @param i the index
217 | * @param delta the value to add
218 | * @return the previous value
219 | */
220 | public final int getAndAdd(int i, int delta) {
221 | long offset = checkedByteOffset(i);
222 | while (true) {
223 | int current = getRaw(offset);
224 | if (compareAndSetRaw(offset, current, current + delta))
225 | return current;
226 | }
227 | }
228 |
229 | /**
230 | * Atomically increments by one the element at index {@code i}.
231 | *
232 | * @param i the index
233 | * @return the updated value
234 | */
235 | public final int incrementAndGet(int i) {
236 | return addAndGet(i, 1);
237 | }
238 |
239 | /**
240 | * Atomically decrements by one the element at index {@code i}.
241 | *
242 | * @param i the index
243 | * @return the updated value
244 | */
245 | public final int decrementAndGet(int i) {
246 | return addAndGet(i, -1);
247 | }
248 |
249 | /**
250 | * Atomically adds the given value to the element at index {@code i}.
251 | *
252 | * @param i the index
253 | * @param delta the value to add
254 | * @return the updated value
255 | */
256 | public final int addAndGet(int i, int delta) {
257 | long offset = checkedByteOffset(i);
258 | while (true) {
259 | int current = getRaw(offset);
260 | int next = current + delta;
261 | if (compareAndSetRaw(offset, current, next))
262 | return next;
263 | }
264 | }
265 |
266 | /**
267 | * Returns the String representation of the current values of array.
268 | * @return the String representation of the current values of array
269 | */
270 | public String toString() {
271 | int iMax = array.length - 1;
272 | if (iMax == -1)
273 | return "[]";
274 |
275 | StringBuilder b = new StringBuilder();
276 | b.append('[');
277 | for (int i = 0; ; i++) {
278 | b.append(getRaw(byteOffset(i)));
279 | if (i == iMax)
280 | return b.append(']').toString();
281 | b.append(',').append(' ');
282 | }
283 | }
284 |
285 | }
286 |
--------------------------------------------------------------------------------
/TheArtOFMultiprocessorProgramming/concurrent/atomic/package-info.java:
--------------------------------------------------------------------------------
1 | /*
2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3 | *
4 | * This code is free software; you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License version 2 only, as
6 | * published by the Free Software Foundation. Oracle designates this
7 | * particular file as subject to the "Classpath" exception as provided
8 | * by Oracle in the LICENSE file that accompanied this code.
9 | *
10 | * This code is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 | * version 2 for more details (a copy is included in the LICENSE file that
14 | * accompanied this code).
15 | *
16 | * You should have received a copy of the GNU General Public License version
17 | * 2 along with this work; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 | *
20 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 | * or visit www.oracle.com if you need additional information or have any
22 | * questions.
23 | */
24 |
25 | /*
26 | * This file is available under and governed by the GNU General Public
27 | * License version 2 only, as published by the Free Software Foundation.
28 | * However, the following notice accompanied the original version of this
29 | * file:
30 | *
31 | * Written by Doug Lea with assistance from members of JCP JSR-166
32 | * Expert Group and released to the public domain, as explained at
33 | * http://creativecommons.org/publicdomain/zero/1.0/
34 | */
35 |
36 | /**
37 | * A small toolkit of classes that support lock-free thread-safe
38 | * programming on single variables. In essence, the classes in this
39 | * package extend the notion of {@code volatile} values, fields, and
40 | * array elements to those that also provide an atomic conditional update
41 | * operation of the form:
42 | *
43 | * This method (which varies in argument types across different
48 | * classes) atomically sets a variable to the {@code updateValue} if it
49 | * currently holds the {@code expectedValue}, reporting {@code true} on
50 | * success. The classes in this package also contain methods to get and
51 | * unconditionally set values, as well as a weaker conditional atomic
52 | * update operation {@code weakCompareAndSet} described below.
53 | *
54 | * The specifications of these methods enable implementations to
55 | * employ efficient machine-level atomic instructions that are available
56 | * on contemporary processors. However on some platforms, support may
57 | * entail some form of internal locking. Thus the methods are not
58 | * strictly guaranteed to be non-blocking --
59 | * a thread may block transiently before performing the operation.
60 | *
61 | * Instances of classes
62 | * {@link java.util.concurrent.atomic.AtomicBoolean},
63 | * {@link java.util.concurrent.atomic.AtomicInteger},
64 | * {@link java.util.concurrent.atomic.AtomicLong}, and
65 | * {@link java.util.concurrent.atomic.AtomicReference}
66 | * each provide access and updates to a single variable of the
67 | * corresponding type. Each class also provides appropriate utility
68 | * methods for that type. For example, classes {@code AtomicLong} and
69 | * {@code AtomicInteger} provide atomic increment methods. One
70 | * application is to generate sequence numbers, as in:
71 | *
72 | * The memory effects for accesses and updates of atomics generally
83 | * follow the rules for volatiles, as stated in section 17.4 of
84 | * The Java™ Language Specification.
85 | *
86 | * In addition to classes representing single values, this package
115 | * contains Updater classes that can be used to obtain
116 | * {@code compareAndSet} operations on any selected {@code volatile}
117 | * field of any selected class.
118 | *
119 | * {@link java.util.concurrent.atomic.AtomicReferenceFieldUpdater},
120 | * {@link java.util.concurrent.atomic.AtomicIntegerFieldUpdater}, and
121 | * {@link java.util.concurrent.atomic.AtomicLongFieldUpdater} are
122 | * reflection-based utilities that provide access to the associated
123 | * field types. These are mainly of use in atomic data structures in
124 | * which several {@code volatile} fields of the same node (for
125 | * example, the links of a tree node) are independently subject to
126 | * atomic updates. These classes enable greater flexibility in how
127 | * and when to use atomic updates, at the expense of more awkward
128 | * reflection-based setup, less convenient usage, and weaker
129 | * guarantees.
130 | *
131 | * The
132 | * {@link java.util.concurrent.atomic.AtomicIntegerArray},
133 | * {@link java.util.concurrent.atomic.AtomicLongArray}, and
134 | * {@link java.util.concurrent.atomic.AtomicReferenceArray} classes
135 | * further extend atomic operation support to arrays of these types.
136 | * These classes are also notable in providing {@code volatile} access
137 | * semantics for their array elements, which is not supported for
138 | * ordinary arrays.
139 | *
140 | *
141 | * The atomic classes also support method {@code weakCompareAndSet},
142 | * which has limited applicability. On some platforms, the weak version
143 | * may be more efficient than {@code compareAndSet} in the normal case,
144 | * but differs in that any given invocation of the
145 | * {@code weakCompareAndSet} method may return {@code false}
146 | * spuriously (that is, for no apparent reason) The {@link java.util.concurrent.atomic.AtomicMarkableReference}
165 | * class associates a single boolean with a reference. For example, this
166 | * bit might be used inside a data structure to mean that the object
167 | * being referenced has logically been deleted.
168 | *
169 | * The {@link java.util.concurrent.atomic.AtomicStampedReference}
170 | * class associates an integer value with a reference. This may be
171 | * used for example, to represent version numbers corresponding to
172 | * series of updates.
173 | *
174 | * Atomic classes are designed primarily as building blocks for
175 | * implementing non-blocking data structures and related infrastructure
176 | * classes. The {@code compareAndSet} method is not a general
177 | * replacement for locking. It applies only when critical updates for an
178 | * object are confined to a single variable.
179 | *
180 | * Atomic classes are not general purpose replacements for
181 | * {@code java.lang.Integer} and related classes. They do not
182 | * define methods such as {@code hashCode} and
183 | * {@code compareTo}. (Because atomic variables are expected to be
184 | * mutated, they are poor choices for hash table keys.) Additionally,
185 | * classes are provided only for those types that are commonly useful in
186 | * intended applications. For example, there is no atomic class for
187 | * representing {@code byte}. In those infrequent cases where you would
188 | * like to do so, you can use an {@code AtomicInteger} to hold
189 | * {@code byte} values, and cast appropriately.
190 | *
191 | * You can also hold floats using
192 | * {@link java.lang.Float#floatToIntBits} and
193 | * {@link java.lang.Float#intBitsToFloat} conversions, and doubles using
194 | * {@link java.lang.Double#doubleToLongBits} and
195 | * {@link java.lang.Double#longBitsToDouble} conversions.
196 | *
197 | * @since 1.5
198 | */
199 | package java.util.concurrent.atomic;
200 |
--------------------------------------------------------------------------------
/TheArtOFMultiprocessorProgramming/concurrent/atomic/AtomicReferenceFieldUpdater.java:
--------------------------------------------------------------------------------
1 | /*
2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3 | *
4 | * This code is free software; you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License version 2 only, as
6 | * published by the Free Software Foundation. Oracle designates this
7 | * particular file as subject to the "Classpath" exception as provided
8 | * by Oracle in the LICENSE file that accompanied this code.
9 | *
10 | * This code is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 | * version 2 for more details (a copy is included in the LICENSE file that
14 | * accompanied this code).
15 | *
16 | * You should have received a copy of the GNU General Public License version
17 | * 2 along with this work; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 | *
20 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 | * or visit www.oracle.com if you need additional information or have any
22 | * questions.
23 | */
24 |
25 | /*
26 | * This file is available under and governed by the GNU General Public
27 | * License version 2 only, as published by the Free Software Foundation.
28 | * However, the following notice accompanied the original version of this
29 | * file:
30 | *
31 | * Written by Doug Lea with assistance from members of JCP JSR-166
32 | * Expert Group and released to the public domain, as explained at
33 | * http://creativecommons.org/publicdomain/zero/1.0/
34 | */
35 |
36 | package java.util.concurrent.atomic;
37 | import sun.misc.Unsafe;
38 | import java.lang.reflect.*;
39 |
40 | /**
41 | * A reflection-based utility that enables atomic updates to
42 | * designated {@code volatile} reference fields of designated
43 | * classes. This class is designed for use in atomic data structures
44 | * in which several reference fields of the same node are
45 | * independently subject to atomic updates. For example, a tree node
46 | * might be declared as
47 | *
48 | * Note that the guarantees of the {@code compareAndSet}
65 | * method in this class are weaker than in other atomic classes.
66 | * Because this class cannot ensure that all uses of the field
67 | * are appropriate for purposes of atomic access, it can
68 | * guarantee atomicity only with respect to other invocations of
69 | * {@code compareAndSet} and {@code set} on the same updater.
70 | *
71 | * @since 1.5
72 | * @author Doug Lea
73 | * @param May fail spuriously
125 | * and does not provide ordering guarantees, so is only rarely an
126 | * appropriate alternative to {@code compareAndSet}.
127 | *
128 | * @param obj An object whose field to conditionally set
129 | * @param expect the expected value
130 | * @param update the new value
131 | * @return true if successful.
132 | */
133 | public abstract boolean weakCompareAndSet(T obj, V expect, V update);
134 |
135 | /**
136 | * Sets the field of the given object managed by this updater to the
137 | * given updated value. This operation is guaranteed to act as a volatile
138 | * store with respect to subsequent invocations of {@code compareAndSet}.
139 | *
140 | * @param obj An object whose field to set
141 | * @param newValue the new value
142 | */
143 | public abstract void set(T obj, V newValue);
144 |
145 | /**
146 | * Eventually sets the field of the given object managed by this
147 | * updater to the given updated value.
148 | *
149 | * @param obj An object whose field to set
150 | * @param newValue the new value
151 | * @since 1.6
152 | */
153 | public abstract void lazySet(T obj, V newValue);
154 |
155 | /**
156 | * Gets the current value held in the field of the given object managed
157 | * by this updater.
158 | *
159 | * @param obj An object whose field to get
160 | * @return the current value
161 | */
162 | public abstract V get(T obj);
163 |
164 | /**
165 | * Atomically sets the field of the given object managed by this updater
166 | * to the given value and returns the old value.
167 | *
168 | * @param obj An object whose field to get and set
169 | * @param newValue the new value
170 | * @return the previous value
171 | */
172 | public V getAndSet(T obj, V newValue) {
173 | for (;;) {
174 | V current = get(obj);
175 | if (compareAndSet(obj, current, newValue))
176 | return current;
177 | }
178 | }
179 |
180 | private static final class AtomicReferenceFieldUpdaterImpl Note that the guarantees of the {@code compareAndSet}
48 | * method in this class are weaker than in other atomic classes.
49 | * Because this class cannot ensure that all uses of the field
50 | * are appropriate for purposes of atomic access, it can
51 | * guarantee atomicity only with respect to other invocations of
52 | * {@code compareAndSet} and {@code set} on the same updater.
53 | *
54 | * @since 1.5
55 | * @author Doug Lea
56 | * @param May fail spuriously
106 | * and does not provide ordering guarantees, so is only rarely an
107 | * appropriate alternative to {@code compareAndSet}.
108 | *
109 | * @param obj An object whose field to conditionally set
110 | * @param expect the expected value
111 | * @param update the new value
112 | * @return true if successful
113 | * @throws ClassCastException if {@code obj} is not an instance
114 | * of the class possessing the field established in the constructor
115 | */
116 | public abstract boolean weakCompareAndSet(T obj, int expect, int update);
117 |
118 | /**
119 | * Sets the field of the given object managed by this updater to the
120 | * given updated value. This operation is guaranteed to act as a volatile
121 | * store with respect to subsequent invocations of {@code compareAndSet}.
122 | *
123 | * @param obj An object whose field to set
124 | * @param newValue the new value
125 | */
126 | public abstract void set(T obj, int newValue);
127 |
128 | /**
129 | * Eventually sets the field of the given object managed by this
130 | * updater to the given updated value.
131 | *
132 | * @param obj An object whose field to set
133 | * @param newValue the new value
134 | * @since 1.6
135 | */
136 | public abstract void lazySet(T obj, int newValue);
137 |
138 |
139 | /**
140 | * Gets the current value held in the field of the given object managed
141 | * by this updater.
142 | *
143 | * @param obj An object whose field to get
144 | * @return the current value
145 | */
146 | public abstract int get(T obj);
147 |
148 | /**
149 | * Atomically sets the field of the given object managed by this updater
150 | * to the given value and returns the old value.
151 | *
152 | * @param obj An object whose field to get and set
153 | * @param newValue the new value
154 | * @return the previous value
155 | */
156 | public int getAndSet(T obj, int newValue) {
157 | for (;;) {
158 | int current = get(obj);
159 | if (compareAndSet(obj, current, newValue))
160 | return current;
161 | }
162 | }
163 |
164 | /**
165 | * Atomically increments by one the current value of the field of the
166 | * given object managed by this updater.
167 | *
168 | * @param obj An object whose field to get and set
169 | * @return the previous value
170 | */
171 | public int getAndIncrement(T obj) {
172 | for (;;) {
173 | int current = get(obj);
174 | int next = current + 1;
175 | if (compareAndSet(obj, current, next))
176 | return current;
177 | }
178 | }
179 |
180 | /**
181 | * Atomically decrements by one the current value of the field of the
182 | * given object managed by this updater.
183 | *
184 | * @param obj An object whose field to get and set
185 | * @return the previous value
186 | */
187 | public int getAndDecrement(T obj) {
188 | for (;;) {
189 | int current = get(obj);
190 | int next = current - 1;
191 | if (compareAndSet(obj, current, next))
192 | return current;
193 | }
194 | }
195 |
196 | /**
197 | * Atomically adds the given value to the current value of the field of
198 | * the given object managed by this updater.
199 | *
200 | * @param obj An object whose field to get and set
201 | * @param delta the value to add
202 | * @return the previous value
203 | */
204 | public int getAndAdd(T obj, int delta) {
205 | for (;;) {
206 | int current = get(obj);
207 | int next = current + delta;
208 | if (compareAndSet(obj, current, next))
209 | return current;
210 | }
211 | }
212 |
213 | /**
214 | * Atomically increments by one the current value of the field of the
215 | * given object managed by this updater.
216 | *
217 | * @param obj An object whose field to get and set
218 | * @return the updated value
219 | */
220 | public int incrementAndGet(T obj) {
221 | for (;;) {
222 | int current = get(obj);
223 | int next = current + 1;
224 | if (compareAndSet(obj, current, next))
225 | return next;
226 | }
227 | }
228 |
229 | /**
230 | * Atomically decrements by one the current value of the field of the
231 | * given object managed by this updater.
232 | *
233 | * @param obj An object whose field to get and set
234 | * @return the updated value
235 | */
236 | public int decrementAndGet(T obj) {
237 | for (;;) {
238 | int current = get(obj);
239 | int next = current - 1;
240 | if (compareAndSet(obj, current, next))
241 | return next;
242 | }
243 | }
244 |
245 | /**
246 | * Atomically adds the given value to the current value of the field of
247 | * the given object managed by this updater.
248 | *
249 | * @param obj An object whose field to get and set
250 | * @param delta the value to add
251 | * @return the updated value
252 | */
253 | public int addAndGet(T obj, int delta) {
254 | for (;;) {
255 | int current = get(obj);
256 | int next = current + delta;
257 | if (compareAndSet(obj, current, next))
258 | return next;
259 | }
260 | }
261 |
262 | /**
263 | * Standard hotspot implementation using intrinsics
264 | */
265 | private static class AtomicIntegerFieldUpdaterImpl This class associates, with each thread that uses it, a permit
46 | * (in the sense of the {@link java.util.concurrent.Semaphore
47 | * Semaphore} class). A call to {@code park} will return immediately
48 | * if the permit is available, consuming it in the process; otherwise
49 | * it may block. A call to {@code unpark} makes the permit
50 | * available, if it was not already available. (Unlike with Semaphores
51 | * though, permits do not accumulate. There is at most one.)
52 | *
53 | * Methods {@code park} and {@code unpark} provide efficient
54 | * means of blocking and unblocking threads that do not encounter the
55 | * problems that cause the deprecated methods {@code Thread.suspend}
56 | * and {@code Thread.resume} to be unusable for such purposes: Races
57 | * between one thread invoking {@code park} and another thread trying
58 | * to {@code unpark} it will preserve liveness, due to the
59 | * permit. Additionally, {@code park} will return if the caller's
60 | * thread was interrupted, and timeout versions are supported. The
61 | * {@code park} method may also return at any other time, for "no
62 | * reason", so in general must be invoked within a loop that rechecks
63 | * conditions upon return. In this sense {@code park} serves as an
64 | * optimization of a "busy wait" that does not waste as much time
65 | * spinning, but must be paired with an {@code unpark} to be
66 | * effective.
67 | *
68 | * The three forms of {@code park} each also support a
69 | * {@code blocker} object parameter. This object is recorded while
70 | * the thread is blocked to permit monitoring and diagnostic tools to
71 | * identify the reasons that threads are blocked. (Such tools may
72 | * access blockers using method {@link #getBlocker}.) The use of these
73 | * forms rather than the original forms without this parameter is
74 | * strongly encouraged. The normal argument to supply as a
75 | * {@code blocker} within a lock implementation is {@code this}.
76 | *
77 | * These methods are designed to be used as tools for creating
78 | * higher-level synchronization utilities, and are not in themselves
79 | * useful for most concurrency control applications. The {@code park}
80 | * method is designed for use only in constructions of the form:
81 | * Sample Usage. Here is a sketch of a first-in-first-out
88 | * non-reentrant lock class:
89 | * If the permit is available then it is consumed and the call returns
160 | * immediately; otherwise
161 | * the current thread becomes disabled for thread scheduling
162 | * purposes and lies dormant until one of three things happens:
163 | *
164 | * This method does not report which of these caused the
175 | * method to return. Callers should re-check the conditions which caused
176 | * the thread to park in the first place. Callers may also determine,
177 | * for example, the interrupt status of the thread upon return.
178 | *
179 | * @param blocker the synchronization object responsible for this
180 | * thread parking
181 | * @since 1.6
182 | */
183 | public static void park(Object blocker) {
184 | Thread t = Thread.currentThread();
185 | setBlocker(t, blocker);
186 | unsafe.park(false, 0L);
187 | setBlocker(t, null);
188 | }
189 |
190 | /**
191 | * Disables the current thread for thread scheduling purposes, for up to
192 | * the specified waiting time, unless the permit is available.
193 | *
194 | * If the permit is available then it is consumed and the call
195 | * returns immediately; otherwise the current thread becomes disabled
196 | * for thread scheduling purposes and lies dormant until one of four
197 | * things happens:
198 | *
199 | * This method does not report which of these caused the
212 | * method to return. Callers should re-check the conditions which caused
213 | * the thread to park in the first place. Callers may also determine,
214 | * for example, the interrupt status of the thread, or the elapsed time
215 | * upon return.
216 | *
217 | * @param blocker the synchronization object responsible for this
218 | * thread parking
219 | * @param nanos the maximum number of nanoseconds to wait
220 | * @since 1.6
221 | */
222 | public static void parkNanos(Object blocker, long nanos) {
223 | if (nanos > 0) {
224 | Thread t = Thread.currentThread();
225 | setBlocker(t, blocker);
226 | unsafe.park(false, nanos);
227 | setBlocker(t, null);
228 | }
229 | }
230 |
231 | /**
232 | * Disables the current thread for thread scheduling purposes, until
233 | * the specified deadline, unless the permit is available.
234 | *
235 | * If the permit is available then it is consumed and the call
236 | * returns immediately; otherwise the current thread becomes disabled
237 | * for thread scheduling purposes and lies dormant until one of four
238 | * things happens:
239 | *
240 | * This method does not report which of these caused the
253 | * method to return. Callers should re-check the conditions which caused
254 | * the thread to park in the first place. Callers may also determine,
255 | * for example, the interrupt status of the thread, or the current time
256 | * upon return.
257 | *
258 | * @param blocker the synchronization object responsible for this
259 | * thread parking
260 | * @param deadline the absolute time, in milliseconds from the Epoch,
261 | * to wait until
262 | * @since 1.6
263 | */
264 | public static void parkUntil(Object blocker, long deadline) {
265 | Thread t = Thread.currentThread();
266 | setBlocker(t, blocker);
267 | unsafe.park(true, deadline);
268 | setBlocker(t, null);
269 | }
270 |
271 | /**
272 | * Returns the blocker object supplied to the most recent
273 | * invocation of a park method that has not yet unblocked, or null
274 | * if not blocked. The value returned is just a momentary
275 | * snapshot -- the thread may have since unblocked or blocked on a
276 | * different blocker object.
277 | *
278 | * @param t the thread
279 | * @return the blocker
280 | * @throws NullPointerException if argument is null
281 | * @since 1.6
282 | */
283 | public static Object getBlocker(Thread t) {
284 | if (t == null)
285 | throw new NullPointerException();
286 | return unsafe.getObjectVolatile(t, parkBlockerOffset);
287 | }
288 |
289 | /**
290 | * Disables the current thread for thread scheduling purposes unless the
291 | * permit is available.
292 | *
293 | * If the permit is available then it is consumed and the call
294 | * returns immediately; otherwise the current thread becomes disabled
295 | * for thread scheduling purposes and lies dormant until one of three
296 | * things happens:
297 | *
298 | * This method does not report which of these caused the
310 | * method to return. Callers should re-check the conditions which caused
311 | * the thread to park in the first place. Callers may also determine,
312 | * for example, the interrupt status of the thread upon return.
313 | */
314 | public static void park() {
315 | unsafe.park(false, 0L);
316 | }
317 |
318 | /**
319 | * Disables the current thread for thread scheduling purposes, for up to
320 | * the specified waiting time, unless the permit is available.
321 | *
322 | * If the permit is available then it is consumed and the call
323 | * returns immediately; otherwise the current thread becomes disabled
324 | * for thread scheduling purposes and lies dormant until one of four
325 | * things happens:
326 | *
327 | * This method does not report which of these caused the
340 | * method to return. Callers should re-check the conditions which caused
341 | * the thread to park in the first place. Callers may also determine,
342 | * for example, the interrupt status of the thread, or the elapsed time
343 | * upon return.
344 | *
345 | * @param nanos the maximum number of nanoseconds to wait
346 | */
347 | public static void parkNanos(long nanos) {
348 | if (nanos > 0)
349 | unsafe.park(false, nanos);
350 | }
351 |
352 | /**
353 | * Disables the current thread for thread scheduling purposes, until
354 | * the specified deadline, unless the permit is available.
355 | *
356 | * If the permit is available then it is consumed and the call
357 | * returns immediately; otherwise the current thread becomes disabled
358 | * for thread scheduling purposes and lies dormant until one of four
359 | * things happens:
360 | *
361 | * This method does not report which of these caused the
374 | * method to return. Callers should re-check the conditions which caused
375 | * the thread to park in the first place. Callers may also determine,
376 | * for example, the interrupt status of the thread, or the current time
377 | * upon return.
378 | *
379 | * @param deadline the absolute time, in milliseconds from the Epoch,
380 | * to wait until
381 | */
382 | public static void parkUntil(long deadline) {
383 | unsafe.park(true, deadline);
384 | }
385 | }
386 |
--------------------------------------------------------------------------------
/TheArtOFMultiprocessorProgramming/locks/Lock.java:
--------------------------------------------------------------------------------
1 | /*
2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3 | *
4 | * This code is free software; you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License version 2 only, as
6 | * published by the Free Software Foundation. Oracle designates this
7 | * particular file as subject to the "Classpath" exception as provided
8 | * by Oracle in the LICENSE file that accompanied this code.
9 | *
10 | * This code is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 | * version 2 for more details (a copy is included in the LICENSE file that
14 | * accompanied this code).
15 | *
16 | * You should have received a copy of the GNU General Public License version
17 | * 2 along with this work; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 | *
20 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 | * or visit www.oracle.com if you need additional information or have any
22 | * questions.
23 | */
24 |
25 | /*
26 | * This file is available under and governed by the GNU General Public
27 | * License version 2 only, as published by the Free Software Foundation.
28 | * However, the following notice accompanied the original version of this
29 | * file:
30 | *
31 | * Written by Doug Lea with assistance from members of JCP JSR-166
32 | * Expert Group and released to the public domain, as explained at
33 | * http://creativecommons.org/publicdomain/zero/1.0/
34 | */
35 |
36 | package java.util.concurrent.locks;
37 | import java.util.concurrent.TimeUnit;
38 |
39 | /**
40 | * {@code Lock} implementations provide more extensive locking
41 | * operations than can be obtained using {@code synchronized} methods
42 | * and statements. They allow more flexible structuring, may have
43 | * quite different properties, and may support multiple associated
44 | * {@link Condition} objects.
45 | *
46 | * A lock is a tool for controlling access to a shared resource by
47 | * multiple threads. Commonly, a lock provides exclusive access to a
48 | * shared resource: only one thread at a time can acquire the lock and
49 | * all access to the shared resource requires that the lock be
50 | * acquired first. However, some locks may allow concurrent access to
51 | * a shared resource, such as the read lock of a {@link ReadWriteLock}.
52 | *
53 | * The use of {@code synchronized} methods or statements provides
54 | * access to the implicit monitor lock associated with every object, but
55 | * forces all lock acquisition and release to occur in a block-structured way:
56 | * when multiple locks are acquired they must be released in the opposite
57 | * order, and all locks must be released in the same lexical scope in which
58 | * they were acquired.
59 | *
60 | * While the scoping mechanism for {@code synchronized} methods
61 | * and statements makes it much easier to program with monitor locks,
62 | * and helps avoid many common programming errors involving locks,
63 | * there are occasions where you need to work with locks in a more
64 | * flexible way. For example, some algorithms for traversing
65 | * concurrently accessed data structures require the use of
66 | * "hand-over-hand" or "chain locking": you
67 | * acquire the lock of node A, then node B, then release A and acquire
68 | * C, then release B and acquire D and so on. Implementations of the
69 | * {@code Lock} interface enable the use of such techniques by
70 | * allowing a lock to be acquired and released in different scopes,
71 | * and allowing multiple locks to be acquired and released in any
72 | * order.
73 | *
74 | * With this increased flexibility comes additional
75 | * responsibility. The absence of block-structured locking removes the
76 | * automatic release of locks that occurs with {@code synchronized}
77 | * methods and statements. In most cases, the following idiom
78 | * should be used:
79 | *
80 | * {@code Lock} implementations provide additional functionality
95 | * over the use of {@code synchronized} methods and statements by
96 | * providing a non-blocking attempt to acquire a lock ({@link
97 | * #tryLock()}), an attempt to acquire the lock that can be
98 | * interrupted ({@link #lockInterruptibly}, and an attempt to acquire
99 | * the lock that can timeout ({@link #tryLock(long, TimeUnit)}).
100 | *
101 | * A {@code Lock} class can also provide behavior and semantics
102 | * that is quite different from that of the implicit monitor lock,
103 | * such as guaranteed ordering, non-reentrant usage, or deadlock
104 | * detection. If an implementation provides such specialized semantics
105 | * then the implementation must document those semantics.
106 | *
107 | * Note that {@code Lock} instances are just normal objects and can
108 | * themselves be used as the target in a {@code synchronized} statement.
109 | * Acquiring the
110 | * monitor lock of a {@code Lock} instance has no specified relationship
111 | * with invoking any of the {@link #lock} methods of that instance.
112 | * It is recommended that to avoid confusion you never use {@code Lock}
113 | * instances in this way, except within their own implementation.
114 | *
115 | * Except where noted, passing a {@code null} value for any
116 | * parameter will result in a {@link NullPointerException} being
117 | * thrown.
118 | *
119 | * All {@code Lock} implementations must enforce the same
122 | * memory synchronization semantics as provided by the built-in monitor
123 | * lock, as described in section 17.4 of
124 | * The Java™ Language Specification:
125 | * The three forms of lock acquisition (interruptible,
139 | * non-interruptible, and timed) may differ in their performance
140 | * characteristics, ordering guarantees, or other implementation
141 | * qualities. Further, the ability to interrupt the ongoing
142 | * acquisition of a lock may not be available in a given {@code Lock}
143 | * class. Consequently, an implementation is not required to define
144 | * exactly the same guarantees or semantics for all three forms of
145 | * lock acquisition, nor is it required to support interruption of an
146 | * ongoing lock acquisition. An implementation is required to clearly
147 | * document the semantics and guarantees provided by each of the
148 | * locking methods. It must also obey the interruption semantics as
149 | * defined in this interface, to the extent that interruption of lock
150 | * acquisition is supported: which is either totally, or only on
151 | * method entry.
152 | *
153 | * As interruption generally implies cancellation, and checks for
154 | * interruption are often infrequent, an implementation can favor responding
155 | * to an interrupt over normal method return. This is true even if it can be
156 | * shown that the interrupt occurred after another action may have unblocked
157 | * the thread. An implementation should document this behavior.
158 | *
159 | * @see ReentrantLock
160 | * @see Condition
161 | * @see ReadWriteLock
162 | *
163 | * @since 1.5
164 | * @author Doug Lea
165 | */
166 | public interface Lock {
167 |
168 | /**
169 | * Acquires the lock.
170 | *
171 | * If the lock is not available then the current thread becomes
172 | * disabled for thread scheduling purposes and lies dormant until the
173 | * lock has been acquired.
174 | *
175 | * Implementation Considerations
176 | *
177 | * A {@code Lock} implementation may be able to detect erroneous use
178 | * of the lock, such as an invocation that would cause deadlock, and
179 | * may throw an (unchecked) exception in such circumstances. The
180 | * circumstances and the exception type must be documented by that
181 | * {@code Lock} implementation.
182 | */
183 | void lock();
184 |
185 | /**
186 | * Acquires the lock unless the current thread is
187 | * {@linkplain Thread#interrupt interrupted}.
188 | *
189 | * Acquires the lock if it is available and returns immediately.
190 | *
191 | * If the lock is not available then the current thread becomes
192 | * disabled for thread scheduling purposes and lies dormant until
193 | * one of two things happens:
194 | *
195 | * If the current thread:
202 | * Implementation Considerations
211 | *
212 | * The ability to interrupt a lock acquisition in some
213 | * implementations may not be possible, and if possible may be an
214 | * expensive operation. The programmer should be aware that this
215 | * may be the case. An implementation should document when this is
216 | * the case.
217 | *
218 | * An implementation can favor responding to an interrupt over
219 | * normal method return.
220 | *
221 | * A {@code Lock} implementation may be able to detect
222 | * erroneous use of the lock, such as an invocation that would
223 | * cause deadlock, and may throw an (unchecked) exception in such
224 | * circumstances. The circumstances and the exception type must
225 | * be documented by that {@code Lock} implementation.
226 | *
227 | * @throws InterruptedException if the current thread is
228 | * interrupted while acquiring the lock (and interruption
229 | * of lock acquisition is supported).
230 | */
231 | void lockInterruptibly() throws InterruptedException;
232 |
233 | /**
234 | * Acquires the lock only if it is free at the time of invocation.
235 | *
236 | * Acquires the lock if it is available and returns immediately
237 | * with the value {@code true}.
238 | * If the lock is not available then this method will return
239 | * immediately with the value {@code false}.
240 | *
241 | * A typical usage idiom for this method would be:
242 | * If the lock is available this method returns immediately
267 | * with the value {@code true}.
268 | * If the lock is not available then
269 | * the current thread becomes disabled for thread scheduling
270 | * purposes and lies dormant until one of three things happens:
271 | * If the lock is acquired then the value {@code true} is returned.
279 | *
280 | * If the current thread:
281 | * If the specified waiting time elapses then the value {@code false}
290 | * is returned.
291 | * If the time is
292 | * less than or equal to zero, the method will not wait at all.
293 | *
294 | * Implementation Considerations
295 | *
296 | * The ability to interrupt a lock acquisition in some implementations
297 | * may not be possible, and if possible may
298 | * be an expensive operation.
299 | * The programmer should be aware that this may be the case. An
300 | * implementation should document when this is the case.
301 | *
302 | * An implementation can favor responding to an interrupt over normal
303 | * method return, or reporting a timeout.
304 | *
305 | * A {@code Lock} implementation may be able to detect
306 | * erroneous use of the lock, such as an invocation that would cause
307 | * deadlock, and may throw an (unchecked) exception in such circumstances.
308 | * The circumstances and the exception type must be documented by that
309 | * {@code Lock} implementation.
310 | *
311 | * @param time the maximum time to wait for the lock
312 | * @param unit the time unit of the {@code time} argument
313 | * @return {@code true} if the lock was acquired and {@code false}
314 | * if the waiting time elapsed before the lock was acquired
315 | *
316 | * @throws InterruptedException if the current thread is interrupted
317 | * while acquiring the lock (and interruption of lock
318 | * acquisition is supported)
319 | */
320 | boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
321 |
322 | /**
323 | * Releases the lock.
324 | *
325 | * Implementation Considerations
326 | *
327 | * A {@code Lock} implementation will usually impose
328 | * restrictions on which thread can release a lock (typically only the
329 | * holder of the lock can release it) and may throw
330 | * an (unchecked) exception if the restriction is violated.
331 | * Any restrictions and the exception
332 | * type must be documented by that {@code Lock} implementation.
333 | */
334 | void unlock();
335 |
336 | /**
337 | * Returns a new {@link Condition} instance that is bound to this
338 | * {@code Lock} instance.
339 | *
340 | * Before waiting on the condition the lock must be held by the
341 | * current thread.
342 | * A call to {@link Condition#await()} will atomically release the lock
343 | * before waiting and re-acquire the lock before the wait returns.
344 | *
345 | * Implementation Considerations
346 | *
347 | * The exact operation of the {@link Condition} instance depends on
348 | * the {@code Lock} implementation and must be documented by that
349 | * implementation.
350 | *
351 | * @return A new {@link Condition} instance for this {@code Lock} instance
352 | * @throws UnsupportedOperationException if this {@code Lock}
353 | * implementation does not support conditions
354 | */
355 | Condition newCondition();
356 | }
357 |
--------------------------------------------------------------------------------
/TheArtOFMultiprocessorProgramming/concurrent/atomic/AtomicLongFieldUpdater.java:
--------------------------------------------------------------------------------
1 | /*
2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3 | *
4 | * This code is free software; you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License version 2 only, as
6 | * published by the Free Software Foundation. Oracle designates this
7 | * particular file as subject to the "Classpath" exception as provided
8 | * by Oracle in the LICENSE file that accompanied this code.
9 | *
10 | * This code is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 | * version 2 for more details (a copy is included in the LICENSE file that
14 | * accompanied this code).
15 | *
16 | * You should have received a copy of the GNU General Public License version
17 | * 2 along with this work; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 | *
20 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 | * or visit www.oracle.com if you need additional information or have any
22 | * questions.
23 | */
24 |
25 | /*
26 | * This file is available under and governed by the GNU General Public
27 | * License version 2 only, as published by the Free Software Foundation.
28 | * However, the following notice accompanied the original version of this
29 | * file:
30 | *
31 | * Written by Doug Lea with assistance from members of JCP JSR-166
32 | * Expert Group and released to the public domain, as explained at
33 | * http://creativecommons.org/publicdomain/zero/1.0/
34 | */
35 |
36 | package java.util.concurrent.atomic;
37 | import sun.misc.Unsafe;
38 | import java.lang.reflect.*;
39 |
40 | /**
41 | * A reflection-based utility that enables atomic updates to
42 | * designated {@code volatile long} fields of designated classes.
43 | * This class is designed for use in atomic data structures in which
44 | * several fields of the same node are independently subject to atomic
45 | * updates.
46 | *
47 | * Note that the guarantees of the {@code compareAndSet}
48 | * method in this class are weaker than in other atomic classes.
49 | * Because this class cannot ensure that all uses of the field
50 | * are appropriate for purposes of atomic access, it can
51 | * guarantee atomicity only with respect to other invocations of
52 | * {@code compareAndSet} and {@code set} on the same updater.
53 | *
54 | * @since 1.5
55 | * @author Doug Lea
56 | * @param May fail spuriously
109 | * and does not provide ordering guarantees, so is only rarely an
110 | * appropriate alternative to {@code compareAndSet}.
111 | *
112 | * @param obj An object whose field to conditionally set
113 | * @param expect the expected value
114 | * @param update the new value
115 | * @return true if successful.
116 | * @throws ClassCastException if {@code obj} is not an instance
117 | * of the class possessing the field established in the constructor.
118 | */
119 | public abstract boolean weakCompareAndSet(T obj, long expect, long update);
120 |
121 | /**
122 | * Sets the field of the given object managed by this updater to the
123 | * given updated value. This operation is guaranteed to act as a volatile
124 | * store with respect to subsequent invocations of {@code compareAndSet}.
125 | *
126 | * @param obj An object whose field to set
127 | * @param newValue the new value
128 | */
129 | public abstract void set(T obj, long newValue);
130 |
131 | /**
132 | * Eventually sets the field of the given object managed by this
133 | * updater to the given updated value.
134 | *
135 | * @param obj An object whose field to set
136 | * @param newValue the new value
137 | * @since 1.6
138 | */
139 | public abstract void lazySet(T obj, long newValue);
140 |
141 | /**
142 | * Gets the current value held in the field of the given object managed
143 | * by this updater.
144 | *
145 | * @param obj An object whose field to get
146 | * @return the current value
147 | */
148 | public abstract long get(T obj);
149 |
150 | /**
151 | * Atomically sets the field of the given object managed by this updater
152 | * to the given value and returns the old value.
153 | *
154 | * @param obj An object whose field to get and set
155 | * @param newValue the new value
156 | * @return the previous value
157 | */
158 | public long getAndSet(T obj, long newValue) {
159 | for (;;) {
160 | long current = get(obj);
161 | if (compareAndSet(obj, current, newValue))
162 | return current;
163 | }
164 | }
165 |
166 | /**
167 | * Atomically increments by one the current value of the field of the
168 | * given object managed by this updater.
169 | *
170 | * @param obj An object whose field to get and set
171 | * @return the previous value
172 | */
173 | public long getAndIncrement(T obj) {
174 | for (;;) {
175 | long current = get(obj);
176 | long next = current + 1;
177 | if (compareAndSet(obj, current, next))
178 | return current;
179 | }
180 | }
181 |
182 | /**
183 | * Atomically decrements by one the current value of the field of the
184 | * given object managed by this updater.
185 | *
186 | * @param obj An object whose field to get and set
187 | * @return the previous value
188 | */
189 | public long getAndDecrement(T obj) {
190 | for (;;) {
191 | long current = get(obj);
192 | long next = current - 1;
193 | if (compareAndSet(obj, current, next))
194 | return current;
195 | }
196 | }
197 |
198 | /**
199 | * Atomically adds the given value to the current value of the field of
200 | * the given object managed by this updater.
201 | *
202 | * @param obj An object whose field to get and set
203 | * @param delta the value to add
204 | * @return the previous value
205 | */
206 | public long getAndAdd(T obj, long delta) {
207 | for (;;) {
208 | long current = get(obj);
209 | long next = current + delta;
210 | if (compareAndSet(obj, current, next))
211 | return current;
212 | }
213 | }
214 |
215 | /**
216 | * Atomically increments by one the current value of the field of the
217 | * given object managed by this updater.
218 | *
219 | * @param obj An object whose field to get and set
220 | * @return the updated value
221 | */
222 | public long incrementAndGet(T obj) {
223 | for (;;) {
224 | long current = get(obj);
225 | long next = current + 1;
226 | if (compareAndSet(obj, current, next))
227 | return next;
228 | }
229 | }
230 |
231 | /**
232 | * Atomically decrements by one the current value of the field of the
233 | * given object managed by this updater.
234 | *
235 | * @param obj An object whose field to get and set
236 | * @return the updated value
237 | */
238 | public long decrementAndGet(T obj) {
239 | for (;;) {
240 | long current = get(obj);
241 | long next = current - 1;
242 | if (compareAndSet(obj, current, next))
243 | return next;
244 | }
245 | }
246 |
247 | /**
248 | * Atomically adds the given value to the current value of the field of
249 | * the given object managed by this updater.
250 | *
251 | * @param obj An object whose field to get and set
252 | * @param delta the value to add
253 | * @return the updated value
254 | */
255 | public long addAndGet(T obj, long delta) {
256 | for (;;) {
257 | long current = get(obj);
258 | long next = current + delta;
259 | if (compareAndSet(obj, current, next))
260 | return next;
261 | }
262 | }
263 |
264 | private static class CASUpdater
88 | *
109 | * You should consider all of these things when evaluating the suitability
110 | * of a given implementation for your application.
111 | *
112 | * @see ReentrantReadWriteLock
113 | * @see Lock
114 | * @see ReentrantLock
115 | *
116 | * @since 1.5
117 | * @author Doug Lea
118 | */
119 | public interface ReadWriteLock {
120 | /**
121 | * Returns the lock used for reading.
122 | *
123 | * @return the lock used for reading.
124 | */
125 | Lock readLock();
126 |
127 | /**
128 | * Returns the lock used for writing.
129 | *
130 | * @return the lock used for writing.
131 | */
132 | Lock writeLock();
133 | }
134 |
--------------------------------------------------------------------------------
/TheArtOFMultiprocessorProgramming/TheArtOFMultiprocessorProgramming.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
44 | * boolean compareAndSet(expectedValue, updateValue);
45 | *
46 | *
47 | *
73 | * class Sequencer {
74 | * private final AtomicLong sequenceNumber
75 | * = new AtomicLong(0);
76 | * public long next() {
77 | * return sequenceNumber.getAndIncrement();
78 | * }
79 | * }
80 | *
81 | *
82 | *
87 | *
88 | *
113 | *
114 | * {@code
49 | * class Node {
50 | * private volatile Node left, right;
51 | *
52 | * private static final AtomicReferenceFieldUpdater
63 | *
64 | * while (!canProceed()) { ... LockSupport.park(this); }
82 | * where neither {@code canProceed} nor any other actions prior to the
83 | * call to {@code park} entail locking or blocking. Because only one
84 | * permit is associated with each thread, any intermediary uses of
85 | * {@code park} could interfere with its intended effects.
86 | *
87 | * {@code
90 | * class FIFOMutex {
91 | * private final AtomicBoolean locked = new AtomicBoolean(false);
92 | * private final Queue
118 | */
119 |
120 | public class LockSupport {
121 | private LockSupport() {} // Cannot be instantiated.
122 |
123 | // Hotspot implementation via intrinsics API
124 | private static final Unsafe unsafe = Unsafe.getUnsafe();
125 | private static final long parkBlockerOffset;
126 |
127 | static {
128 | try {
129 | parkBlockerOffset = unsafe.objectFieldOffset
130 | (java.lang.Thread.class.getDeclaredField("parkBlocker"));
131 | } catch (Exception ex) { throw new Error(ex); }
132 | }
133 |
134 | private static void setBlocker(Thread t, Object arg) {
135 | // Even though volatile, hotspot doesn't need a write barrier here.
136 | unsafe.putObject(t, parkBlockerOffset, arg);
137 | }
138 |
139 | /**
140 | * Makes available the permit for the given thread, if it
141 | * was not already available. If the thread was blocked on
142 | * {@code park} then it will unblock. Otherwise, its next call
143 | * to {@code park} is guaranteed not to block. This operation
144 | * is not guaranteed to have any effect at all if the given
145 | * thread has not been started.
146 | *
147 | * @param thread the thread to unpark, or {@code null}, in which case
148 | * this operation has no effect
149 | */
150 | public static void unpark(Thread thread) {
151 | if (thread != null)
152 | unsafe.unpark(thread);
153 | }
154 |
155 | /**
156 | * Disables the current thread for thread scheduling purposes unless the
157 | * permit is available.
158 | *
159 | *
165 | *
173 | *
174 | *
200 | *
210 | *
211 | *
241 | *
251 | *
252 | *
299 | *
300 | *
308 | *
309 | *
328 | *
338 | *
339 | *
362 | *
372 | *
373 | * Lock l = ...;
81 | * l.lock();
82 | * try {
83 | * // access the resource protected by this lock
84 | * } finally {
85 | * l.unlock();
86 | * }
87 | *
88 | *
89 | * When locking and unlocking occur in different scopes, care must be
90 | * taken to ensure that all code that is executed while the lock is
91 | * held is protected by try-finally or try-catch to ensure that the
92 | * lock is released when necessary.
93 | *
94 | * Memory Synchronization
120 | *
121 | *
126 | *
131 | *
132 | * Unsuccessful locking and unlocking operations, and reentrant
133 | * locking/unlocking operations, do not require any memory
134 | * synchronization effects.
135 | *
136 | * Implementation Considerations
137 | *
138 | *
196 | *
200 | *
201 | *
203 | *
207 | * then {@link InterruptedException} is thrown and the current thread's
208 | * interrupted status is cleared.
209 | *
210 | *
243 | * Lock lock = ...;
244 | * if (lock.tryLock()) {
245 | * try {
246 | * // manipulate protected state
247 | * } finally {
248 | * lock.unlock();
249 | * }
250 | * } else {
251 | * // perform alternative actions
252 | * }
253 | *
254 | * This usage ensures that the lock is unlocked if it was acquired, and
255 | * doesn't try to unlock if the lock was not acquired.
256 | *
257 | * @return {@code true} if the lock was acquired and
258 | * {@code false} otherwise
259 | */
260 | boolean tryLock();
261 |
262 | /**
263 | * Acquires the lock if it is free within the given waiting time and the
264 | * current thread has not been {@linkplain Thread#interrupt interrupted}.
265 | *
266 | *
272 | *
277 | *
278 | *
282 | *
286 | * then {@link InterruptedException} is thrown and the current thread's
287 | * interrupted status is cleared.
288 | *
289 | *