1.2.2 线程安全之原子性操作

什么是原子操作

一个或若干个操作看成一个整体,要不全不执行要不全部不执行

可见性问题和原子性问题的区别

  • 可见性问题
    是一个人修改了但另一个人不能够及时的看见
  • 原子性问题
    读取了值之后,值失效了

这些问题产生的原因

  1. 因为CPU高速缓存
  2. 因为线程的独占内存和主内存的关系:所有的变量都在主内存有一份原件,每个线程运行的时候会去主内存拷贝一份,如果线程对变量有修改的话,就把最新的值同步到主内存,这就导致之间会有线程不安全的问题
  3. 指令重排,jit编译(运行时编译)会对代码进行优化,譬如
while(flag){}

在经历了N次循环后,编译器会认为永远都不会等于0,然后优化成

if(flag==true)
{
  while(true){}
}

解决可见性问题的方法:volatile

  1. 用volatile关键字描述的变量,虽然仍然会在线程的独占内存里有一份拷贝,但是每次读取之前,仍然会去主内存读取一次
  2. 使用了volatile修饰的变量,相关的代码不会进行指令重排。

CAS COMPARED AND SWAP 比较与交换

这是硬件级别的用来解决原子性问题的一个方法,它需要两个值

  • 旧值
  • 新值
    在把新值写到内存之前,把旧值跟内存的值比较,如果一样的话,才把新值写进内存,否则的话,放弃这次操作。

UNSAFE JVM级别的CAS工具类

AtmoicInteger、AtmoicIntegerArray、AtmoicReferenceArray之类的

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容