synchronized 与 volatile
Posted leifonlyone
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了synchronized 与 volatile相关的知识,希望对你有一定的参考价值。
synchronized 与 volatile:
可见性:一个线程对共享变量的修改,能够及时的被其他线程看到
所有的变量都储存在主内存中,每个线程独有自己独立的工作内存,里面保存着主内存中该变量的拷贝副本
线程对共享变量的操作都必须在自己的工作内存中进行不能直接在主内存中读写。不同线程中的变量值需要通过主内存传递。
Synchronized:可以实现原子性(同步)、可见性。线程解锁前必须把共享变量的最新值刷新到主内存中。加锁时会清空工作内存中共享变量的值,从而使用共享变量时会重新从主内存中读取最新变量值(加锁解锁需要是同一把锁)。
重排序:代码书写顺序与实际执行顺序不一致 是编译器或者处理器为提高程序执行性能而做的优化
共享变量线程间不可见原因:重排序、线程交叉执行、共享变量值更新后没有在工作内存和主内存间及时更新
Synchronized 加到方法上时默认使用当前对象锁。方法一旦执行,就会独占该锁,一直到从该方法返回时或者出现异常时 jvm才将锁释放,此后被阻塞的线程方能获得该锁,从而重新进入可执行状态。
运行结果多运行几次会发现 如果不加synchronized 多个线程会存在交叉运行如:002、022或者线程的先后顺序会变化如002、222。 加了synchronized后虽然线程的先后顺序会变化但会一直到从该方法返回。
Volitale:可见性通过加入内存屏障和禁止指令重排序 在执行写操作时会在写操作后加入一条store屏障指令强制刷新主内存,读操作时会在读操作前加入一条load屏障指令使缓存中的变量值失效 这样每次读取变量值都需要从主内存中读取 不保证原子性 如num++ 循环100 最后的值可能会小于100 修饰共享变量时可保证单线程的原子性。
以上是关于synchronized 与 volatile的主要内容,如果未能解决你的问题,请参考以下文章
2.3.7synchronized代码块有volatile同步的功能