Skip to content

Commit 2d8165c

Browse files
committed
更新
1 parent 2403c24 commit 2d8165c

File tree

1 file changed

+41
-33
lines changed

1 file changed

+41
-33
lines changed

2.Java Concurrent.md

Lines changed: 41 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -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() {
686687
AtomicStampedReference解决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
724733
Thread-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

731739
AtomicMarkableReference 通过标志位,由于其标志位只有true和false,如果每次更新都变更标志位,在第三次的时候标志位还是跟第一次一样,并没有解决ABA问题

0 commit comments

Comments
 (0)