@@ -284,6 +284,7 @@ public class CopyOnWriteArrayListTest {
284284 pool- 1 - thread- 2
285285 pool- 1 - thread- 2 ,执行结束
286286 pool- 1 - thread- 1 ,执行结束
287+ # 等待所有线程都执行完成
287288 ```
288289
289290
@@ -310,7 +311,7 @@ public class PhaserTest {
310311
311312 executor. submit(() - > {
312313 System . out. println(Thread . currentThread(). getName() + " step2" );
313- phaser. arrive(d );
314+ phaser. arrive();
314315 });
315316
316317 // 等同await()
@@ -404,6 +405,8 @@ Thread2:1
404405
405406什么时候使用volatile?
406407
408+ - 有一个变量,这个变量需要被多线程检查某个条件,此时使用volatile确保每次都从主内存读取
409+
407410- 写入变量值不依赖变量的当前值。因为如果依赖当前值,将是获取-计算-写入三步操作,这三步操作不是原子性的,而volatile不保证原子性
408411
409412- 读写变量值时没有加锁。因为加锁已经保证了内存可见性,没必要再使用volatile
@@ -446,8 +449,6 @@ Thread2:1
446449
447450> @Contended 注解只用于Java 核心类,如果用户类路径下的类要使用这个注解,需要添加JVM 参数:- XX : - RestrictContended 。默认填充宽度为128 ,需要自定义宽度设置 - XX : ContendedPaddingWidth 参数
448451
449- > CPU 缓存行详细说明:https: // mp.weixin.qq.com/s/yosnZr0bDdLrhmpnX8TY5A
450-
451452### 原子操作类
452453
453454 ** AtomicBoolean **
@@ -686,46 +687,53 @@ public void test1() {
686687AtomicStampedReference解决ABA问题,通过维护一个版本号
687688
688689``` java
689- @SneakyThrows
690- @Test
691- public void test2() {
692- AtomicStampedReference<Integer > atomicStampedReference = new AtomicStampedReference (10 ,1 );
693-
694- CountDownLatch countDownLatch = new CountDownLatch (2 );
690+ // AtomicStampedReference,通过维护一个版本号
691+ @SneakyThrows
692+ @Test
693+ public void test2() {
694+ AtomicStampedReference<Integer > atomicStampedReference = new AtomicStampedReference (10 ,1 );
695695
696- new Thread (() - > {
697- System . out. println(Thread . currentThread(). getName() + " 第一次版本:" + atomicStampedReference. getStamp());
698- atomicStampedReference. compareAndSet(10 , 11 , atomicStampedReference. getStamp(), atomicStampedReference. getStamp() + 1 );
699- System . out. println(Thread . currentThread(). getName() + " 第二次版本:" + atomicStampedReference. getStamp());
700- atomicStampedReference. compareAndSet(11 , 10 , atomicStampedReference. getStamp(), atomicStampedReference. getStamp() + 1 );
701- System . out. println(Thread . currentThread(). getName() + " 第三次版本:" + atomicStampedReference. getStamp());
702- countDownLatch. countDown();
703- }). start();
696+ CountDownLatch countDownLatch = new CountDownLatch (2 );
704697
705- new Thread (() - > {
706- System . out. println(Thread . currentThread(). getName() + " 第一次版本:" + atomicStampedReference. getStamp());
707- try {
708- TimeUnit . SECONDS. sleep(2 );
709- boolean isSuccess = atomicStampedReference. compareAndSet(10 ,12 , atomicStampedReference. getStamp(), atomicStampedReference. getStamp() + 1 );
710- System . out. println(Thread . currentThread(). getName() + " 修改是否成功:" + isSuccess + " 当前版本:" + atomicStampedReference. getStamp() + " 当前值:" + atomicStampedReference. getReference());
698+ new Thread (() - > {
699+ // 使用第一次获取的版本,因为不知道有其他线程偷摸改了
700+ int stamp = atomicStampedReference. getStamp();
701+ System . out. println(Thread . currentThread(). getName() + " 第一次版本:" + stamp);
702+ try {
703+ // 等待一下
704+ TimeUnit . SECONDS. sleep(2 );
705+ // 这个线程打算修改10->12
706+ boolean isSuccess = atomicStampedReference. compareAndSet(10 ,12 , stamp, stamp + 1 );
707+ System . out. println(Thread . currentThread(). getName() + " 修改是否成功:" + isSuccess + " 当前版本:" + atomicStampedReference. getStamp() + " 当前值:" + atomicStampedReference. getReference());
708+ countDownLatch. countDown();
709+ } catch (InterruptedException e) {
710+ e. printStackTrace();
711+ }
712+ }). start();
713+
714+ new Thread (() - > {
715+ // 这个线程偷摸的把10->11->10
716+ System . out. println(Thread . currentThread(). getName() + " 第一次版本:" + atomicStampedReference. getStamp());
717+ atomicStampedReference. compareAndSet(10 , 11 , atomicStampedReference. getStamp(), atomicStampedReference. getStamp() + 1 );
718+ System . out. println(Thread . currentThread(). getName() + " 第二次版本:" + atomicStampedReference. getStamp());
719+ atomicStampedReference. compareAndSet(11 , 10 , atomicStampedReference. getStamp(), atomicStampedReference. getStamp() + 1 );
720+ System . out. println(Thread . currentThread(). getName() + " 第三次版本:" + atomicStampedReference. getStamp());
711721 countDownLatch. countDown();
712- } catch (InterruptedException e) {
713- e. printStackTrace();
714- }
715- }). start();
722+ }). start();
716723
717- countDownLatch. await();
718- }
724+
725+ countDownLatch. await();
726+ }
719727
720728```
721729
722730``` java
723731// 输出
732+ Thread - 1 第一次版本:1
724733Thread - 0 第一次版本:1
725- Thread - 0 第二次版本:2
726- Thread - 0 第三次版本:3
727- Thread - 1 第一次版本:3
728- Thread - 1 修改是否成功:true 当前版本:4 当前值:12
734+ Thread - 1 第二次版本:2
735+ Thread - 1 第三次版本:3
736+ Thread - 0 修改是否成功:false 当前版本:3 当前值:10
729737```
730738
731739AtomicMarkableReference 通过标志位,由于其标志位只有true和false,如果每次更新都变更标志位,在第三次的时候标志位还是跟第一次一样,并没有解决ABA问题
0 commit comments