1. Synchronized如何保证原子性、可见性和有序性
原子性:确保线程互斥的访问同步代码;
可见性:保证共享变量的修改对其他线程能够及时可见。
- 线程解锁前,必须把共享变量的最新值刷新到主内存中
- 线程加锁时,将清空工作内存中共享变量的值,从而使用共享变量时需要从主内存中重新获取最新的值
有序性:对一个监视器锁的释放操作先行发生(happens-before)与后面对该监视器锁的获取操作
2. Synchronized使用形式
- 对于普通同步方法,锁对象是当前实例对象。
- 对于静态同步方法,锁对象是当前类的Class对象。
- 对于同步方法块,锁对象是Synchonized括号里配置的对象。
3. Synchronized的缺点
各种锁并不是相互代替的,而是在不同场景下的不同选择,绝对不是说重量级锁就是不合适的。Synchronized只能升级,不能降级,即由偏向锁->轻量级锁->重量级锁,而这个过程就是开销逐渐加大的过程。
- 如果是单线程使用,那偏向锁毫无疑问代价最小,并且它就能解决问题,连CAS都不用做,仅仅在内存中比较下对象头就可以了;
- 如果出现了其他线程竞争,则偏向锁就会升级为轻量级锁;
- 如果其他线程通过一定次数的CAS尝试没有成功,则进入重量级锁;
比如我现在是滴滴,我早上有打车高峰,我代码使用了大量的synchronized,有什么问题?锁升级过程是不可逆的,过了高峰我们还是重量级的锁,那效率是不是大打折扣了?这个时候你用Lock是不是很好?——三太子敖丙