Java 中的锁

Java 中对象的锁其实主要就是通过对象头的Mark Word进行表示的。
对于 HotSpot 虚拟机就是
\hotspot\src\share\vm\oops\markOop.hpp
对象头
Mark Word 不是一个对象,只是一个字长的数据。在32为机器上,Mark Word 为32位,在64位上为64位。
Mark Word 中不同的位区域存储着不同的信息,但是需要注意的一点是,Mark Word 每个区域表示的信息不是一定的,在不同状态下,Mark Word中存着不同的信息。
这里写图片描述


乐观锁

乐观锁是对于数据冲突保持一种乐观态度,操作数据时不会对数据锁定(这使得多个任务可以并行的对数据进行操作),只有到数据提交的时候才通过一种机制来验证数据是否存在冲突(一般是通过加版本号然后进行比对的方式实现);

特点:乐观锁是一种并发类型的锁,本身不对数据进行加锁通过业务实现锁的功能,不对数据进行加锁就意味着允许多个请求同时访问数据,这种方式大大的提高了并发数据请求的性能。

Java JUC中的atomic包就是乐观锁的一种实现。如 AtomicInteger 通过CAS(Compare And Set)操作实现线程安全的自增。

悲观锁

悲观锁是基于一种悲观的态度来防止一切数据冲突,它是以一种预防的姿态在修改数据之前把数据锁住然后再对数据进行读写,在它释放锁之前任何人都不能对其数据进行操作,直到前面一个人把锁释放后下一个人才可对数据进行加锁,然后才可以对数据进行操作。

特点:可以完全保证操作数据的独占性和正确性,但因其加锁释放锁的过程会造成消耗,所以性能不高;

Java synchronized(JDK1.5前) 就属于悲观锁的一种实现,每次线程要修改数据时都先获得锁,保证同一时刻只有一个线程能操作数据,其他线程则会被 block。

乐观锁和悲观锁的最主要区别是有没有加锁。
悲观锁:假定会发生并发冲突,屏蔽一切可能违反数据完整性的操作。
乐观锁:假设不会发生并发冲突,只在提交操作时检查是否违反数据完整性。


偏向锁

锁偏向是一种针对加锁操作的优化手段。它的核心思想是:如果一个线程获得了锁,那么锁就进入偏向模式。当这个线程再次请求锁时,无须再做任何同步操作。这样就节省了大量有关锁申请的操作,从而提高了程序性能。因此,对于几乎没有锁竞争的场合,偏向锁有比较好的优化效果,因为连续多次极有可能是同一个线程请求相同的锁。而对于锁竞争比较激烈的场合,其效果不佳。因为在竞争激烈的场合,最有可能的情况是每次都是不同的线程来请求相同的锁。这样偏向模式会失效,因此还不如不启用偏向锁

总之,偏向锁应对的是被同一个线程进行访问的情况,此时根本就没有发生并发,故每次加锁都会损失性能。

偏向,也可以理解为偏心。当锁对象第一次被某个线程访问时,它会在其对象头的 markOop 中记录该线程ID,那么下次该线程再次访问它时,就不需要进行加锁了。
但是这中间只要发生了其他线程访问该锁对象的情况,证明这个对象会发生并发,就不能对这个对象再使用偏向锁了,会进行锁的升级。

轻量级锁

这里写图片描述

重量级锁

在JDK1.5之前都是使用synchronized关键字保证同步的,synchronized 就是一种重量级锁。


这里写图片描述
这里写图片描述

https://www.zhihu.com/question/55075763/answer/142524888
https://www.jianshu.com/p/f5ff017db62a
https://blog.csdn.net/hongchangfirst/article/details/26004335

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

N3verL4nd

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值