Java并发之显式锁和隐式锁的区别

在面试的过程中有可能会问到:在Java并发编程中,锁有两种实现:使用隐式锁和使用显示锁分别是什么?两者的区别是什么?所谓的显式锁和隐式锁的区别也就是说说Synchronized(下文简称:sync)和lock(下文就用ReentrantLock来代之lock)的区别。

本文主要内容:将通过七个方面详细介绍sync和lock的区别。通过生活case中的X二代和普通人比较大家更容易理解这两者之间的区别

Java中隐式锁:synchronized;显式锁:lock

sync和lock的区别

一:出身不同

从sync和lock的出身(原始的构成)来看看两者的不同。

Sync:Java中的关键字,是由JVM来维护的。是JVM层面的锁。

Lock:是JDK5以后才出现的具体的类。使用lock是调用对应的API。是API层面的锁

sync是底层是通过monitorenter进行加锁(底层是通过monitor对象来完成的,其中的wait/notify等方法也是依赖于monitor对象的。只有在同步块或者是同步方法中才可以调用wait/notify等方法的。因为只有在同步块或者是同步方法中,JVM才会调用monitory对象的);通过monitorexit来退出锁的。

而lock是通过调用对应的API方法来获取锁和释放锁的。

我们通过Javap命令来查看调用sync和lock的汇编指令:

编辑

从编译后的汇编指令,我们也能够清晰的看出sync关键字和lock的区别。

第一不同一句话概述:可以把sync理解为官二代或者是星二代。从娘胎出来自带光环的。Lock就是我们普通努力上进的人。

二:使用方式不同

Sync是隐式锁。Lock是显示锁

所谓的显示和隐式就是在使用的时候,使用者要不要手动写代码去获取锁和释放锁的操作。

我们大家都知道,在使用sync关键字的时候,我们使用者根本不用写其他的代码,然后程序就能够获取锁和释放锁了。那是因为当sync代码块执行完成之后,系统会自动的让程序释放占用的锁。Sync是由系统维护的,如果非逻辑问题的话话,是不会出现死锁的。

在使用lock的时候,我们使用者需要手动的获取和释放锁。如果没有释放锁,就有可能导致出现死锁的现象。手动获取锁方法:lock.lock()。释放锁:unlock方法。需要配合tyr/finaly语句块来完成。

两者用法对比如下:

编辑

用生活中的一个case来形容这个不同:官二代和普通人的你在进入机关大院的时候待遇。官二代不需要出示什么证件就可以进入,但是你需要手动出示证件才可以进入。

三:等待是否可中断

Sync是不可中断的。除非抛出异常或者正常运行完成

Lock可以中断的。中断方式:

1:调用设置超时方法tryLock(long timeout ,timeUnit unit)

2:调用lockInterruptibly()放到代码块中,然后调用interrupt()方法可以中断

生活中小case来理解这一区别:官二代一般不会做饭。都会去餐厅点餐等待着餐厅出餐。普通人的你既可以去餐厅等待,如果等待时间长的话,你就可以回去自己做饭了。

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

Sync;非公平锁

lock:两者都可以的。默认是非公平锁。在其构造方法的时候可以传入Boolean值。

true:公平锁

false:非公平锁

生活中小case来理解这个区别:官二代一般都不排队,喜欢插队的。普通人的你虽然也喜欢插队。但是如果遇到让排队的情况下,你还是会排队的。

Lock的公平锁和非公平锁:

五:锁绑定多个条件来condition

Sync:没有。要么随机唤醒一个线程;要么是唤醒所有等待的线程。

Lock:用来实现分组唤醒需要唤醒的线程,可以精确的唤醒,而不是像sync那样,不能精确唤醒线程。

六:从性能比较

生活小case理解:在我们一般的认知中,官二代一般都是比较坑爹的吧。但是这几年也有很多官二代或者是富二代改变了态度,端正自己态度,靠自己能力而不是拼爹了。

七:从使用锁的方式比较

欢迎来聊~

Java队列学习第一篇之列介绍的更多相关文章

  1. Java泛型学习--第一篇

    还是那句话,学习某个知识一定要想想为什么要学它,这方面的知识用来解决什么问题的,怎么用,并且要总结的体系化,不能散的到处都是,方便以后查看博客. 今天参考廖雪峰老师官网学习并总结下泛型廖老师官网 1. ...

  2. Java并发包下锁学习第一篇:介绍及学习安排

    Java并发包下锁学习第一篇:介绍及学习安排 在Java并发编程中,实现锁的方式有两种,分别是:可以使用同步锁(synchronized关键字的锁),还有lock接口下的锁.从今天起,凯哥将带领大家一 ...

  3. JVM学习第一篇思考:一个Java代码是怎么运行起来的-上篇

    JVM学习第一篇思考:一个Java代码是怎么运行起来的-上篇 作为一个使用Java语言开发的程序员,我们都知道,要想运行Java程序至少需要安装JRE(安装JDK也没问题).我们也知道我们Java程序 ...

  4. 从.Net到Java学习第一篇——开篇

    以前我常说,公司用什么技术我就学什么.可是对于java,我曾经一度以为“学java是不可能的,这辈子不可能学java的.”结果,一遇到公司转java,我就不得不跑路了,于是乎,回头一看N家公司交过社保 ...

  5. IIS负载均衡-Application Request Route详解第一篇: ARR介绍(转载)

    IIS负载均衡-Application Request Route详解第一篇: ARR介绍 说到负载均衡,相信大家已经不再陌生了,本系列主要介绍在IIS中可以采用的负载均衡的软件:微软的Applica ...

  6. LINQ to XML LINQ学习第一篇

    LINQ to XML LINQ学习第一篇 1.LINQ to XML类 以下的代码演示了如何使用LINQ to XML来快速创建一个xml: public static void CreateDoc ...

  7. [转]ZooKeeper学习第一期---Zookeeper简单介绍

    ZooKeeper学习第一期---Zookeeper简单介绍 http://www.cnblogs.com/sunddenly/p/4033574.html 一.分布式协调技术 在给大家介绍ZooKe ...

  8. IIS负载均衡-Application Request Route详解第一篇: ARR介绍

    IIS负载均衡-Application Request Route详解第一篇: ARR介绍 说到负载均衡,相信大家已经不再陌生了,本系列主要介绍在IIS中可以采用的负载均衡的软件:微软的Applica ...

  9. Java泛型学习---第二篇

    泛型学习第一篇 1.泛型之擦拭法 泛型是一种类似"模板代码"的技术,不同语言的泛型实现方式不一定相同. Java语言的泛型实现方式是擦拭法(Type Erasure). 所谓擦拭法 ...

随机推荐

  1. ssm框架整合---maven工具来导入jar包

    ssm整合 一.导包(pom.xml文件) <?xml version="1.0" encoding="UTF-8"?> <project x ...

  2. 常用的API和基础算法

    和数学相关 1,java.lang.Math类 abs(x):求绝对值 sqrt(x):求平方根 pow(x,y):求x的y次方 ceil(x):向上取整 floor(x):向下取整 round(x) ...

  3. python使用pip安装模块出现ReadTimeoutError: HTTPSConnectionPool的解决方法

    今天使用pip安装第三库时,有时会报错: pip._vendor.urllib3.exceptions.ReadTimeoutError: HTTPSConnectionPool(host='file ...

  4. nginx 自动化定时切割日志

    NG在默认情况下,是始终输出到一个日志文件中,日志文件在nginx.conf中 : access_log  logs/www.access.log  main;  一个文件中不是很方便查找,分析数据, ...

  5. DNN训练技巧(Tips for Training DNN)

    本博客是针对李宏毅教授在Youtube上上传的课程视频<ML Lecture 9-1:Tips for Training DNN>的学习笔记. 课程链接 Recipe of Deep Le ...

  6. TensorFlow系列专题(十三): CNN最全原理剖析(续)

    目录: 前言 卷积层(余下部分) 卷积的基本结构 卷积层 什么是卷积 滑动步长和零填充 池化层 卷积神经网络的基本结构 总结 参考文献   一.前言 上一篇我们一直说到了CNN[1]卷积层的特性,今天 ...

  7. php 设置允许跨域请求

    php 服务端代码 <?php header('Content-Type: text/html;charset=utf-8'); header('Access-Control-Allow-Ori ...

  8. 前端学习(3)-CSS

    一 CSS CSS是Cascading Style Sheets的缩写,层叠样式表,用来控制网页数据的显示,可以使网页的显示与数据内容分离. 二 引入方式 (1)行内式:在标记的style属性中设置C ...

  9. localStorage中一个数组嵌套一个数组的怪相

    localStorage中一个数组嵌套一个数组的怪相 需求:向本地存储中循环添加对象 思路 : ​ 先完成点击事件中添加本地存储功能,当刷新时使用一个数组记录已经存储下来的数据,并在点击事件中将新生成 ...

  10. 深入理解NIO(一)—— NIO的简单使用及其三大组件介绍

    深入理解NIO(一)—— NIO的简单使用及其三大组件介绍 深入理解NIO系列分为四个部分 第一个部分也就是本节为NIO的简单使用(我很少写这种新手教程,所以如果你是复习还好,应该不难理解这篇,但如果 ...