https://www.cnblogs.com/54chensongxia/p/11910681.html
原子操作的相关内容参考以上链接。
写了个Demo如下:
static volatile Integer couter = 0;
static volatile AtomicInteger integer = new AtomicInteger(0);
public static void main(String[] args) throws InterruptedException {
List<Thread> list = new ArrayList<>();
for(int i = 0 ; i < 10000 ; i++){
list.add(new Thread(() -> {
integer.addAndGet(1);
synchronized (couter){
couter++;
}
}));
}
for(Thread t : list){
t.start();
}
for(Thread t : list){
t.join();
}
System.out.println(couter);
System.out.println(integer.get());
}
因为couter++已经加了同步锁,但count的结果依然不正确,运行结果如下:
9997
10000
结论:
因为synchronized (couter)锁的是couter的地址,当couter的值超过127时,couter会使用新Integer对象的地址,导致之前的锁失效。
正确写法:
static volatile Object lock = new Object();
static volatile Integer couter = 0;
static volatile AtomicInteger integer = new AtomicInteger(0);
public static void main(String[] args) throws InterruptedException {
List<Thread> list = new ArrayList<>();
for(int i = 0 ; i < 10000 ; i++){
list.add(new Thread(() -> {
integer.addAndGet(1);
synchronized (lock){
couter++;
}
}));
}
for(Thread t : list){
t.start();
}
for(Thread t : list){
t.join();
}
System.out.println(couter);
System.out.println(integer.get());
}
运行结果:
10000
10000
全部评论