Java中锁的简单介绍

之前在面试的过程中被问到乐观锁和悲观锁,就去网上查了查关于锁的概念,简单做个总结。(锁的种类竟然这么多!!!)

这是网上大多数锁的种类。我们要知道的是,并不是一个锁只属于一个种类,它可以是悲观锁,同时也可以属于公平锁,就像一个人,它可以是一个男人,也可以是一个程序员,也同样可以是一个游戏爱好者。
在Java中,有两种锁的实现方式,一种是用synchronized关键字,另一种是用Lock接口的实现类。
一般在我们写代码时,通常只加synchronized关键字就可以了。(因为本人不常用Lock接口)那两者之间的区别呢,**synchronized是Java语言内置的关键字,而Lock是一个接口,这个接口的实现类在代码层面实现了锁的功能。**简单来说,我们写简单的代码,用synchronized关键字就可以了,但如果想做更多的操作,就要用到Lock接口了。
悲观锁与乐观锁
我们都知道,锁的作用就是当一个线程去操作一个数据时,防止另一个线程也去操作这个数据,造成数据的操作失败。两者之间区别从名字就可以做分辨。
**悲观锁:**就是非常的悲观,他在去操作一个数据时,都会认为一定会有人也去操作这个数据,所以每次在拿数据的时候都会上锁。这样别人想拿数据就被挡住,直到悲观锁被释放。
**乐观锁:**就很乐观,每次去拿数据的时候都认为别人不会修改。也就不会去上锁,但是当它要去修改这个数据时,则会在更新前检查在读取至更新这段时间别人有没有修改过这个数据。如果修改过,则重新读取,再次尝试更新,循环上述步骤直到更新成功(当然也允许更新失败的线程放弃操作)。
悲观锁阻塞事务,乐观锁回滚重试,它们各有优缺点,不要认为一种一定好于另一种。像乐观锁适用于写比较少的情况下,即冲突真的很少发生的时候,这样可以省去锁的开销,加大了系统的整个吞吐量。但如果经常产生冲突,上层应用会不断的进行重试,这样反倒是降低了性能,所以这种情况下用悲观锁就比较合适。
什么是CAS?
就是比较和替换,上边说了乐观锁在修改数据时就是不断的重复“比较和替换”,所以CAS是乐观锁的基础。乐观锁并不会去上锁,解锁。只是不断的去重复这个CAS算法而已。
synchronized关键字
前面说了,synchronized关键字在实现锁时比较简单。一共可分为三种类型。分别为偏向锁、轻量级锁、和重量级锁。
偏向锁:就是偏向第一个获得它的线程。执行完同步代码块后,线程并不会主动释放偏向锁。当第二次到达同步代码块时,线程会判断此时持有锁的线程是否就是自己(持有锁的线程ID也在对象头里),如果是则正常往下执行。由于之前没有释放锁,这里也就不需要重新加锁。如果自始至终使用锁的线程只有一个,很明显偏向锁几乎没有额外开销,性能极高。

轻量级锁:一旦有第二个线程加入锁竞争,偏向锁就升级为轻量级锁(自旋锁)。这里要明确一下什么是锁竞争:如果多个线程轮流获取一个锁,但是每次获取锁的时候都很顺利,没有发生阻塞,那么就不存在锁竞争。只有当某线程尝试获取锁的时候,发现该锁已经被占用,只能等待其释放,这才发生了锁竞争。

在轻量级锁状态下继续锁竞争,没有抢到锁的线程将自旋,即不停地循环判断锁是否能够被成功获取。获取锁的操作,其实就是通过CAS修改对象头里的锁标志位。先比较当前锁标志位是否为“释放”,如果是则将其设置为“锁定”,比较并设置是原子性发生的。这就算抢到锁了,然后线程将当前锁的持有者信息修改为自己。

长时间的自旋操作是非常消耗资源的,一个线程持有锁,其他线程就只能在原地空耗CPU,执行不了任何有效的任务,这种现象叫做忙等(busy-waiting)。如果多个线程用一个锁,但是没有发生锁竞争,或者发生了很轻微的锁竞争,那么synchronized就用轻量级锁,允许短时间的忙等现象。这是一种折衷的想法,短时间的忙等,换取线程在用户态和内核态之间切换的开销。

重量级锁:显然,此忙等是有限度的(有个计数器记录自旋次数,默认允许循环10次,可以通过虚拟机参数更改)。如果锁竞争情况严重,某个达到最大自旋次数的线程,会将轻量级锁升级为重量级锁(依然是CAS修改锁标志位,但不修改持有锁的线程ID)。当后续线程尝试获取锁时,发现被占用的锁是重量级锁,则直接将自己挂起(而不是忙等),等待将来被唤醒。在JDK1.6之前,synchronized直接加重量级锁,很明显现在得到了很好的优化。

一个锁只能按照 偏向锁、轻量级锁、重量级锁的顺序逐渐升级(也有叫锁膨胀的),不允许降级。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值