分析synchronized底层:
每个对象有一个监视器锁(monitor)。当monitor被占用时就会处于锁定状态,线程执行monitorenter指令时尝试获取monitor的所有权,过程如下:
1、如果monitor的进入数为0,则该线程进入monitor,然后将进入数设置为1,该线程即为monitor的所有者。
2、如果线程已经占有该monitor,只是重新进入,则进入monitor的进入数加1.
3.如果其他线程已经占用了monitor,则该线程进入阻塞状态,直到monitor的进入数为0,再重新尝试获取monitor的所有权。
Synchronized的语义底层是通过一个monitor的对象来完成,其实wait/notify等方法也依赖于monitor对象,这就是为什么只有在同步的块或者方法中才能调用wait/notify等方法,否则会抛出java.lang.IllegalMonitorStateException的异常的原因。调用之前都需要先去竞争同一个对象上的锁(monitor),也就只能互斥的获取到锁,保证了线程安全。(synchronized锁是不可逆的,这也是他的很大的一个缺点,场景,滴滴上班高峰期大家都要打车,为了保证线程安全使用了sync锁,那么等高峰期过了,那些对象还是被sync锁定,因为不可逆,一直是重锁,所有很多时候sync锁都是慎重使用的)
案例:
让线程A打印五次,之后让线程B打印10次,然后c打印15次
重复5轮