线程安全性(二)

2019-02-22  本文已影响24人  菜鸟程序员一枚

原子性
提供互斥访问,同一时刻只能有一个线程来对它进行操作

synchronized:依赖于JVM,属于不可中断锁,适合竞争不激烈,可读性好

Lock: 不依赖于JVM,需要手动解锁以及释放锁,属于可中断锁,竞争激烈时能维持常态

Atomic: 竞争激烈时候能保持常态,比Lock性能好,只能同步一个值

CAS算法?????

可见性
一个线程对主内存的修改可以及时的被其他的线程观察到
导致共享变量在线程间不可见的原因
1.线程交叉执行
2.重排序结合线程交叉执行
3.共享变量更行后的值没有在工作内存与主内存间及时更新

synchronized: JMM关于synchronized的两条规定

1).线程解锁前,必须把共享变量的最新值刷新到主内存中
2).线程加锁时,讲清空工作内纯种共享变量的值,从而使用共享变量时需要从主内存中重新读取最新的值(注意,加锁与解锁是同一把锁)

volatile: 通过加入内存屏障和禁止重排序优化来实现

1).对volatile变量写操作时,会在写操作后加入一条store屏障指令,将本地内存中的共享变量值刷新到主内存中
2).对volatile变量读操作时,会在读操作前加入一条load屏障指令,从主内存中读取共享变量

volatile注意事项,应该具备两个条件

1).运算结果并不依赖变量的当前值
2).变量不需要与其他的状态变量共同参与不变的约束
所以说volatile不适用于计数的场景,适用于状态标记量的场景

有序性
一个线程观察其他线程中的指令执行顺序,由于指令重排序的存在,该观察结果一般扎乱无序

上一篇下一篇

猜你喜欢

热点阅读