synchronized的万能(原子,可见,有序)
原子性
- 如果一个变量事先未被Lock锁定,那么不允许对其unlock操作,也不能unlock一个被其他线程锁定的变量。
synchronized隐式使用lock和unlock,保证了lock和unlock操作之间的代码是原子的。
可见性
1.synchronized的内存语义
八大happens-before规则中的两条:
- 对一个变量执行lock操作,必须清空工作内存中此变量的值,在执行引擎使用该变量之前,重新执行load或assign。
- 对一个变量unlock操作之前,必须把此变量同步会主内存。
也就是说, - 当一个线程获取一个锁,这个线程重新从主内存加载最新的数据到本地内存;
- 当一个线程释放一个锁的时候,将该线程本地内存中的最新最正确的数据同步到主内存。
两者结合,可以看出锁的释放,获取的内存语义可以类比volatile变量的读/写的内存语义,锁的释放相当于volatile的写,锁的获取相当于volatile的写。所以锁具备内存可见性。
2.如何实现这样的内存语义
在JVM规范中可以看到JVM中synchronized的实现原理,JVM基于进入和退出Monitor来实现方法同步和代码同步,实现细节不一样,代码同步使用monitorenter,monitorexit两个指令实现,编译器会在同步代码开始处插入monitorenter指令,在结束处或者异常处插入monitorexit指令,==这两个字节码指令隐式使用lock和unlock操作==。
有序性
- 同一时间只有一个线程可以对一个变量进行lock操作,像是把多线程的环境变为了单线程,天然具备有序性(程序顺序规则)
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。