出现线程安全问题的原因:
1、原子性:不同线程对共享变量非原子读写
2、可见性:不同线程使用共享变量时会从主存中复制一份共享变量的副本到自己的本地内存中,副本被修改后不会及时刷新到主存中,其他线程获取到的是未修改时的值
3、有序性:CPU为了执行效率,会把CPU指令进行重新排序,单线程重排序后的执行结果与代码顺序预期的结果一致,多线程重排序则可能会导致运行结果与预期结果不一致
解决方法:
1、原子性:①使用synchronized加锁
②循环CAS操作(Lock和原子类(AtomicInteger))
例:static Lock lock = new Lock ();
lock.lock(); //加锁
count++;
lock.unlock(); //解锁
static AtomicInteger count = new AtomicInteger(0);
count.incrementAndGet(); //自增
count.decrementAndGet(); //自减
2、可见性:①加锁,synchronized和Lock都可以保证
②使用volatile修饰共享变量(修改后会立即刷新到主存,读取变量值时会从主存重新获取)
3、有序性: ①使用volatile修饰变量,被修饰变量读写操作时会保证前面的代码指令已经执行且后面的代码未执行
②加锁,synchronized
参考:【JAVA并发第四篇】线程安全 - 就行222 - 博客园



