文章目录
一、synchronized的作用
synchronized可以给方法和代码块加锁,保证该方法或者该断代码块同一时间智能有同一个线程访问,从而避免了线程安全问题。
二、synchronized中的几种状态
被synchronized加锁的对象中会有五种状态:
- 0(00):轻量级锁状态,该状态下的线程只会进行cas自旋,而不会使用到monitor进行从用户态到内核态的重量级转换操作;
- 1(001):无锁状态,jdk1.6之后,对象创建出来的前4s内都是无锁状态,4s后如果没有线程使用,那么会将该对象置为无偏向的偏向锁状态;
- 2(10):重量级锁状态,线程在该状态下会使用到monitor,进行从用户态到内核态的重量级转换操作;
- 3(101):偏向锁状态,jdk1.6之后默认所有对象都是无指向偏向锁状态,不过该状态要在4s后才会生效。当第一个线程访问该对象的时候,该对象才会改变为指向偏向锁状态;
- 5(11):gc状态,表明当前对象已被垃圾回收器标记,马上就会被回收;
三、synchronized的锁升级原理
- 当线程第一次访问该对象时,当前对象的对象头里面会有一个ThreadId属性来保存当前访问对象的ID,并且会将此时的锁状态调整为偏向锁状态(无锁状态的时候会调整,偏向锁状态的情况下只会写入线程ID)。
- 当第二次有线程来访问该对象时,会先对比ThreadId来判断是否是之前第一次访问的线程,如果是的话就可以直接访问到该对象,如果不是则会进行自旋,并将该对象的偏向锁升级为轻量级锁。
- 当某个线程自旋一定时间后仍旧没有获取到锁无法访问对象的话,它就会使用到monitor进入到队列中,并将对象的锁置为重量级锁状态,等待被唤醒。
四、锁升/降级的注意点
锁升级可以一级一级的递增,但是锁降级只能先降至最低的无锁状态才能转换为其它的状态