@@ -694,7 +694,7 @@ public class ReOrdering implements Runnable {
694694
695695如果你尝试使用 ** volatile** ,你可能更应该尝试让一个变量线程安全而不是引起同步的成本。因为 ** volatile** 使用起来非常微妙和棘手,所以我建议根本不要使用它;相反,请使用本附录后面介绍的 ** java.util.concurrent.atomic** 里面类之一。它们以比同步低得多的成本提供了完全的线程安全性。
696696
697- 如果您正在尝试调试其他人的并发代码 ,请首先查找使用 ** volatile** 的代码并将其替换为** Atomic** 变量。除非你确定程序员对并发性有很高的理解,否则它们很可能会误用 ** volatile** 。
697+ 如果你正在尝试调试其他人的并发代码 ,请首先查找使用 ** volatile** 的代码并将其替换为** Atomic** 变量。除非你确定程序员对并发性有很高的理解,否则它们很可能会误用 ** volatile** 。
698698
699699<!-- Atomicity -->
700700## 原子性
@@ -861,7 +861,7 @@ No failures found
861861
862862只有并发编程专家有能力去尝试做像前面例子情况的优化;再次强调,请遵循 Brain 的同步法则。
863863
864- ### Josh 的序列数字
864+ ### Josh 的序列号
865865
866866作为第二个示例,考虑某些更简单的东西:创建一个产生序列号的类,灵感启发于 Joshua Bloch 的 * Effective Java Programming Language Guide* (Addison-Wesley 出版社, 2001) 第 190 页。每次调用 ` nextSerialNumber() ` 都必须返回唯一值。
867867
@@ -992,6 +992,82 @@ No duplicates detected
992992
993993### 原子类
994994
995+ Java 5 引入了专用的原子变量类,例如 ** AtomicInteger** 、** AtomicLong** 、** AtomicReference** 等。这些提供了原子性升级。这些快速、无锁的操作,它们是利用了现代处理器上可用的机器级原子性。
996+
997+ 下面,我们可以使用 ** atomicinteger** 重写 ** unsafereturn.java** 示例:
998+
999+ ``` java
1000+ // lowlevel/AtomicIntegerTest.java
1001+ import java.util.concurrent.* ;
1002+ import java.util.concurrent.atomic.* ;
1003+ import java.util.* ;
1004+ import onjava.* ;
1005+
1006+ public class AtomicIntegerTest extends IntTestable {
1007+ private AtomicInteger i = new AtomicInteger (0 );
1008+ public int getAsInt () { return i. get(); }
1009+ public void evenIncrement () { i. addAndGet(2 ); }
1010+ public static void main (String [] args ) {
1011+ Atomicity . test(new AtomicIntegerTest ());
1012+ }
1013+ }
1014+ /* Output:
1015+ No failures found
1016+ */
1017+ ```
1018+
1019+ 现在,我们通过使用 ** AtomicInteger** 来消除了 ** synchronized** 关键字。
1020+
1021+ 下面使用 ** AtomicInteger** 来重写 ** SynchronizedEvenProducer.java** 示例:
1022+
1023+ ``` java
1024+ // lowlevel/AtomicEvenProducer.java
1025+ // Atomic classes: occasionally useful in regular code
1026+ import java.util.concurrent.atomic.* ;
1027+
1028+ public class AtomicEvenProducer extends IntGenerator {
1029+ private AtomicInteger currentEvenValue =
1030+ new AtomicInteger (0 );
1031+ @Override
1032+ public int next () {
1033+ return currentEvenValue. addAndGet(2 );
1034+ }
1035+ public static void main (String [] args ) {
1036+ EvenChecker . test(new AtomicEvenProducer ());
1037+ }
1038+ }
1039+ /* Output:
1040+ No odd numbers discovered
1041+ */
1042+ ```
1043+
1044+ 再次,使用 ** AtomicInteger** 消除了对所有其他同步方式的需要。
1045+
1046+ 下面是一个使用 ** AtomicInteger** 实现 ** SerialNumbers** 的例子:
1047+
1048+ ``` java
1049+ // lowlevel/AtomicSerialNumbers.java
1050+ import java.util.concurrent.atomic.* ;
1051+
1052+ public class
1053+ AtomicSerialNumbers extends SerialNumbers {
1054+ private AtomicInteger serialNumber =
1055+ new AtomicInteger ();
1056+ public synchronized int nextSerialNumber() {
1057+ return serialNumber. getAndIncrement();
1058+ }
1059+ public static void main(String [] args) {
1060+ SerialNumberChecker . test(
1061+ new AtomicSerialNumbers ());
1062+ }
1063+ }
1064+ /* Output:
1065+ No duplicates detected
1066+ */
1067+ ```
1068+
1069+ 这些都是对单一字段的简单示例; 当你创建更复杂的类时,你必须确定哪些字段需要保护,在某些情况下,你可能仍然最后在方法上使用 ** synchronized** 关键字。
1070+
9951071<!-- Critical Sections -->
9961072## 临界区
9971073
0 commit comments