package fangfa;
import java.util.concurrent.CountDownLatch;
public class Ljsdjj24324 {
public static void main(String[] args) throws InterruptedException {
Hasdy hasdy = new Hasdy();
CountDownLatch countDownLatch = new CountDownLatch(9999);
for (int i = 0; i < 9999; i++) {
new Thread(()->{
for (int i1 = 0; i1 < 100; i1++) {
hasdy.setaaa();
}
countDownLatch.countDown();
}).start();
}
countDownLatch.await();
Thread.sleep(5000);
System.out.println(hasdy.getasd());
}
}
class Hasdy{
volatile int a = 1;
void setaaa(){
a+=1;
}
int getasd(){
return a;
}
}
volatile并没有保证多线程安全
为什么会这样。
根据Happens-Before规则,先开启的线程对数据的修改对后续线程应该是可见的啊
难道是我理解错了吗?
volatile只能保证内存变化的可见性,不能保证操作的原子性。
你的setaaa()
方法里执行了a+=1
,分析一下这一步实际执行的操作:
第一步有一个从内存载入的操作,假设时刻a有线程1
从内存载入的值为1,时刻b有其他线程修改了内存中的值为5,而线程1
计算得到的值却是2
,这时线程1
将2
刷到内存中,覆盖了5
,这明显就有问题了。
volatile 只能保证可见性和有序性,不能保证原子性,由于 a+=1
不是一个原子操作,因此多线程下会有线程安全问题,导致最后计算的值可能偏小
volatile只能保证内存可见性,即工作线程每次使用变量前都从主内存读取,使用完成后立即写回主内存,但读取与写回在底层是由多条指令完成的,这些指令不具备原子性,故会存在多线程安全问题。
你需要了解一下多线程的内存模型
https://blog.csdn.net/z562743237/article/details/110238128?spm=1001.2014.3001.5501