java 并发编程之 原子性、有序性、可见性
1、java之原子性
原子性概念:一个或多个指令在CPU执行过程中不允许中断的(针对计算型的指令,保证某一个计算执行完后可再次对某个数据进行计算)。
并发编程中原子性带来的问题:在单线程串行执行是不存在原子性问题,但是在多线程在执行在操作共享数据的时候,如果不保证某个计算是原子性的那么会出现预期结果与实际结果不一致的问题,比如对一个整数使用多个线程进行多次+1操作 如果不保证+1这个操作是原子性的那么结果肯定是不对。
如何解决:java层面提供了锁机制,可以使用原生synchronized锁对执行操作的方法加锁或代码块进行加锁,也可以使用
juc并发工具类ReentrantLock对要保证原子性的代码加锁以及使用CAS进行计算的时候也可以保证原子性。
2、java之有序性
有序性概念:CPU在执行指令的时候不一定会按照指令顺序执行,在JAVA程序中如果满足happens-before原则,指令就会发生重排序,那么会导致出现问题。如何解决呢?在你需要保证有序性的地方 使用 volatile 修饰符进行修饰。
3、java之可见性
可见性概念:前面说过CPU在处理时,需要将主内存数据甩到我的寄存机中再执行指令,指向完指令后,需要将寄存器数据扔回到主内存
中。但是寄存器数据同步到主内存是遵循MESI协议的,说人话就是,不是每次操作结束就将CPU缓存数据同步到主内存。造成多个
线程看到的数据不一样。那么如何保证修改完后立即同步到主内存呢?
1. volatile每次操作后,立即同步数据到主内存。
2. synchronized,触发同步数据到主内存。
3. final,也可以解决可见性问题。