我这里稍微模拟了一下:
package com.git.poan.multithreadpractice;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class UnsafeSequence {
private int val;
public int getNextVal() {
return ++val;// 原书使用的是val++;感觉这样效果不直观 ,我用++val
}
public static void main(String[] args) {
int threadNum = 2;
ExecutorService executorService = Executors.newFixedThreadPool(threadNum);
UnsafeSequence unsafeSequence = new UnsafeSequence();
for (int i = 0; i < threadNum; i++) {
final int j = i;
executorService.execute(() -> {
Thread.currentThread().setName("thread-" + j);
int nextVal = unsafeSequence.getNextVal();
System.out.println(Thread.currentThread().getName() + "'s val:" + nextVal);
});
}
}
}
从执行结果上看:
thread-0's val:1
thread-1's val:1
有一定的几率出现上述结果;
出现以上的结果,是因为getNextVal方法中,自己操作本省不是原子性的,实际上分成了三个指令:
实际情况中,如果有多个线程,这里举例用1号和2号线程,1号线程执行到2步骤,2号线程开始执行,那么2号读到的val还是0;
所以会出现两个线程最终对val的自加结果一样的情况。
上述的情况,原书中一开始是通过synchronized,保证其修饰的代码在多线程调用下的同步性
上述代码:
public synchronized int getNextVal() {
return ++val;
}
你看那个人好像一条狗啊