首先看个代码:`
class Resource{
int num=0;
public void add(){
num++;
}
}
public class Main2<fori> {
public static void main(String[] args) throws InterruptedException {
CountDownLatch countDownLatch = new CountDownLatch(10);
Resource resource = new Resource();
for (int i=0;i<10;i++){
new Thread(()->{
for (int j=0;j<1000;j++){
resource.add();
}
countDownLatch.countDown();
}).start();
}
countDownLatch.await();
System.out.println(resource.num);
}
}
运行结果是9718而不是预想的10000
面对这样的情况有两种解决办法:
1.加重锁:synchronized :只能有一个线程对num进行读写
2.CAS+volatile:允许多个线程同时操作,CAS原理就是比较内存值和期望值是否一样,如果一样则更新,不一样则进行自旋,这里用volatile来保证重新从主内存中取到的值是最新值
①没有加volitail的变量i :写覆盖 :两个线程同时读取到内存中的值时,会将重复的值写入内存两次(写的时候并非是同一时刻)
②加了volitail的变量i: 写无效 :两个线程同时读取到内存中的值时 ,两个线程看谁先将值写的内存当中去,如果第一个线程将值写到了内存当中,那么另一个线程加之后的值作废,即当次循环作废
③原子类: 两个线程同时读取到内存中的值时 ,第一个线程修改了值以后,另一个线程不会写无效,而是将内存中的值取出来作为下次cas期望的值,重新cas,