synchronized在Java中是一个关键字,它是由JVM实现的,所以synchronized依赖于操作系统实现。但是synchronized非常的智能,能通过判断整个程序的锁冲突来决定使用什么样的锁策略,对于程序员来说非常的友好。
首先我们要知道synchronized整个锁升级的过程:无锁 —> 偏向锁 —> 轻量级锁 —> 重量级锁,synchronized的升级过程就是以上四个步骤,当锁的竞争越来越激烈的时候synchronized会自动进行升级。
无锁,这里就不需要过多介绍了,在整个程序都不会发生冲突的时候,就是无锁策略
偏向锁:
我们的第一个线程拿到锁之后,系统会标记此线程,当此线程释放锁之后,在尝试拿锁,可以直接通行,并不需要再次进行加锁解锁操作。这有点像这么一个情况,如果你知道燕双鹰可能会更好理解一点,燕双鹰是电视剧上的一个角色,他最喜欢跟别人打赌,赌自己的枪里面有没有子弹。偏向锁也可以理解成在赌是否有其他线程来跟我竞争锁,如果赌成功了,则性能会进一步提升,如果失败了大不了就是竞争,并没有太大的影响,所以偏向锁就是这样一个思想。
轻量级锁:
synchronized升级成轻量级锁,这个轻量级锁就是一个基于CAS实现的自旋锁,如果发现有锁冲突但是不严重的情况下,一个线程先获取到锁,然后另一个线程也想要获取这个锁资源,这时候线程2不会进入进行阻塞等待,而是在CPU上空转,没有放弃CPU,然后每过一段时间就尝试获得锁,这可以使得在自旋的线程可以第一时间获取到锁资源,但是会占用CPU的资源。在我们的锁冲突比较不严重的情况下我们的synchronized就是这样的一个轻量级锁。
重量级锁:
当JVM判断我们整个程序的锁冲突严重的时候就会将synchronized升级成重量级锁,而这个重量级锁就是挂起等待锁。当一个线程获取到锁之后,其他线程会进入阻塞队列中等待,等待锁被释放,然后所有线程再去竞争锁,如果这个锁资源一直不被释放,其他线程就会一直在阻塞队列中一直死等,等到资源被释放。
ps:synchronized只能进行锁升级,不能支持锁降级。