Java显式锁和隐式锁的区别

本文详细对比了Java中Lock和synchronized两种锁机制,包括它们的构成、使用方式、可中断性、公平性、多条件唤醒及性能。Lock提供了更细粒度的控制,如显式获取和释放锁,可中断和公平性选择,但使用不当可能导致死锁。synchronized则由JVM维护,自动释放锁,但不具备Lock的灵活性。在性能方面,现代JVM对synchronized进行了优化,与Lock的差距已不大。
摘要由CSDN通过智能技术生成

Java线程不安全问题有三种解决方案,所谓显式锁和隐式锁即Lock和synchronized的区别。
在这里插入图片描述

一、构成不同

Sync:Java中的关键字,是由JVM来维护的,是JVM层面的锁。
Sync 底层是通过 monitorenter 进行加锁(底层是通过 monitor 对象来完成的,其中的wait/notify等方法也 是依赖于 monitor 对象的。只有在同步代码块或者同步方法中才可以调用wait/notify等方法。因为只有在同步代码块或者是同步方法中,JVM才会调用 monitory 对象);通过 monitorexit 来退出锁。
Lock:是JDK5以后才出现的具体的类。使用 Lock 是调用对应的API,是API层面的锁。
而 Lock 是通过调用对应的API方法来获取锁和释放锁。

二、使用方式不同

Sync是隐式锁,Lock是显示锁。

所谓的显示和隐式就是在使用的时候,使用者要不要手动写代码去获取锁和释放锁的操作。
->在使用sync关键字的时候,程序能够自动获取锁和释放锁。因为当sync代码块执行完成之后,系统会自动让程序释放占用的锁。Sync是由系统维护的,如果非逻辑问题的话,是不会出现死锁的。
->Lock:手动获取和释放,不然可能导致出现死锁的现象。
Demo:
在这里插入图片描述

三、等待是否可中断

Sync是不可中断的,除非抛出异常或者正常运行完成。
Lock可以中断的。
中断方式:
1、调用设置超时方法tryLock(long timeout ,timeUnit unit)
2、调用lockInterruptibly()放到代码块中,然后调用interrupt()方法可以中断

四、加锁的时候是否可以公平

Sync:非公平锁。即排队抢锁。
Lock:两者都可以的。默认是非公平锁。在其构造方法的时候可以传入Boolean值。
true:公平锁。即Lock lo = new ReentrantLock(true)
false:非公平锁

五、锁绑定多个条件来condition

Sync:要么随机唤醒一个线程,要么是唤醒所有等待的线程。
Lock:用来实现分组唤醒需要唤醒的线程,可以精确的唤醒,而不是像sync那样,不能精确唤醒线程。

六、性能比较

Sync是托管给JVM执行的。在JDK5中,前者因为需要调用接口操作,可能加锁等消耗时间更长。但在JDK6后,sync进行很多优化,有适应自旋、锁消除、锁粗化、轻量级锁、偏向锁等,性能也不比lock差。
Lock是java写的控制锁的代码。对象性能更高点。

之前的sync使用悲观锁的机制,即线程独占锁,其它线程只能依靠阻塞来等待线程释放的锁,而线程阻塞时会引起线程的上下文切换,当有很多线程竞争锁的时候,会引起CPU频繁的上下文切换导致效率很低。

而Lock使用乐观锁的方式。所谓乐观锁就是,每次不加锁而是假设没有冲突而去完成某项操作,如果因为冲突失败就重试,直到成功为止。乐观锁的实现方式是CAS机制(Compare And Swap),调用的是CPU提供的底层指令。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值