(手机横屏看源码更方便)

引子

大家知道,我最近在招人,今天遇到个同学,他的源码看过一些,然后我就开始了AQS连环问。

我:说说AQS的大致流程?

他:AQS包含一个状态变量,一个同步队列……balabala……互斥锁balabala,共享锁balabala……

我:AQS中除了同步队列,还有什么队列?

他:还有个Condition,Condition中有个条件队列……

我:条件队列和同步队列有什么区别?

他:条件队列balabala,然后调用LockSupport.park()进入休眠,等待被唤醒,……,balabala

咦,这时我灵感突发:LockSupport.park()和Thread.sleep()有什么区别?

他:Thread.sleep()不会释放锁资源,……,balabala

我:LockSupport.park()会释放锁资源吗?

他:会吧。(估计和Object.wait()搞混淆了)

我:会吗?会吗?会吗?

他(羞涩地低下了头):彤哥,不知道,你的文章里没写。(这段我瞎写的哈^^)

OK,今天我们就来看看LockSupport.park()到底会不会释放锁资源。

Thread.sleep()和Object.wait()的区别

首先,我们先来看看Thread.sleep()和Object.wait()的区别,这是一个烂大街的题目了,大家应该都能说上来两点。

(1)Thread.sleep()不会释放占有的锁,Object.wait()会释放占有的锁;

(2)Thread.sleep()必须传入时间,Object.wait()可传可不传,不传表示一直阻塞下去;

(3)Thread.sleep()到时间了会自动唤醒,然后继续执行;

(4)Object.wait()不带时间的,需要另一个线程使用Object.notify()唤醒;

(5)Object.wait()带时间的,假如没有被notify,到时间了会自动唤醒,这时又分好两种情况,一是立即获取到了锁,线程自然会继续执行;二是没有立即获取锁,线程进入同步队列等待获取锁;

其实,他们俩最大的区别就是Thread.sleep()不会释放锁资源,Object.wait()会释放锁资源。

Thread.sleep()和Condition.await()的区别

我们再来看看Thread.sleep()和Condition.await()的区别。

其实,这个题目和上面的题目比较类似,因为本来Object.wait()和Condition.await()的原理就比较类似,可以参考之前彤哥写的《死磕 java线程系列之线程的生命周期》之篇文章。

这个题目的回答思路跟Object.wait()是基本一致的,不同的是Condition.await()底层是调用LockSupport.park()来实现阻塞当前线程的。

实际上,它在阻塞当前线程之前还干了两件事,一是把当前线程添加到条件队列中,二是“完全”释放锁,也就是让state状态变量变为0,然后才是调用LockSupport.park()阻塞当前线程,可以参考之前彤哥写的《死磕 java同步系列之ReentrantLock源码解析(二)——条件锁》这篇文章。

看到这里,今天开篇提的那个问题是不是就有答案了呢【本文由公从号“彤哥读源码”原创】?

Thread.sleep()和LockSupport.park()的区别

LockSupport.park()还有几个兄弟方法——parkNanos()、parkUtil()等,我们这里说的park()方法统称这一类方法。

(1)从功能上来说,Thread.sleep()和LockSupport.park()方法类似,都是阻塞当前线程的执行,且都不会释放当前线程占有的锁资源

(2)Thread.sleep()没法从外部唤醒,只能自己醒过来;

(3)LockSupport.park()方法可以被另一个线程调用LockSupport.unpark()方法唤醒;

(4)Thread.sleep()方法声明上抛出了InterruptedException中断异常,所以调用者需要捕获这个异常或者再抛出;

(5)LockSupport.park()方法不需要捕获中断异常;

(6)Thread.sleep()本身就是一个native方法;

(7)LockSupport.park()底层是调用的Unsafe的native方法;

Object.wait()和LockSupport.park()的区别

二者都会阻塞当前线程的运行,他们有什么区别呢?经过上面的分析相信你一定很清楚了,真的吗?往下看!

(1)Object.wait()方法需要在synchronized块中执行;

(2)LockSupport.park()可以在任意地方执行;

(3)Object.wait()方法声明抛出了中断异常,调用者需要捕获或者再抛出;

(4)LockSupport.park()不需要捕获中断异常【本文由公从号“彤哥读源码”原创】;

(5)Object.wait()不带超时的,需要另一个线程执行notify()来唤醒,但不一定继续执行后续内容;

(6)LockSupport.park()不带超时的,需要另一个线程执行unpark()来唤醒,一定会继续执行后续内容;

(7)如果在wait()之前执行了notify()会怎样?抛出IllegalMonitorStateException异常

(8)如果在park()之前执行了unpark()会怎样?线程不会被阻塞,直接跳过park(),继续执行后续内容;

最后两点是不是没想到?!

其实,在《死磕 java线程系列之自己动手写一个线程池(续)》这篇文章里代码注释里稍微提到过unpark()这个方法,它先执行,则后续的park()方法将不再起作用。

park()/unpark()底层的原理是“二元信号量”,你可以把它相像成只有一个许可证的Semaphore,只不过这个信号量在重复执行unpark()的时候也不会再增加许可证,最多只有一个许可证。

关于信号量的内容,可以参考《死磕 java同步系列之Semaphore源码解析》这篇文章。

LockSupport.park()会释放锁资源吗?

不会,它只负责阻塞当前线程,释放锁资源实际上是在Condition的await()方法中实现的。

彩蛋

好了,上面我们交叉对比了Thread.sleep()、Object.wait()、Condition.await()、LockSupport.park()的区别。

让我们用一张思维导图结束今天的内容。

thread.sleep会释放锁吗_面试 LockSupport.park()会释放锁资源吗?相关推荐

  1. redis续期_面试官:Redis分布式锁如何解决锁超时问题的?

    一.前言 关于redis分布式锁, 查了很多资料, 发现很多只是实现了最基础的功能, 但是, 并没有解决当锁已超时而业务逻辑还未执行完的问题, 这样会导致: A线程超时时间设为10s(为了解决死锁问题 ...

  2. 事物的级别_面试官问:MySQL锁与事物隔离级别你知道吗?

    本文作者:何建辉(公众号:org_yijiaoqian) 点赞再看,养成习惯,微信搜一搜[一角钱小助手]关注更多原创技术文章. 本文 GitHub org_hejianhui/JavaStudy 已收 ...

  3. Redis 学习笔记-NoSQL数据库 常用五大数据类型 Redis配置文件介绍 Redis的发布和订阅 Redis_事务_锁机制_秒杀 Redis应用问题解决 分布式锁

    1.NoSQL数据库 1.1 NoSQL数据库概述 NoSQL(NosQL = Not Only sQL ),意即"不仅仅是sQL",泛指非关系型的数据库.NoSQL不依赖业务逻辑 ...

  4. mysql锁争用_关于MYSQL条件竞争与锁的问题

    最近在整理关支付安全的内容,其中就是涉及到了一个在支付过程中的条件竞争问题.以下都是基于mysql的与php的架构来描述该问题,大佬勿喷. 0x01. 条件竞争 什么是条件竞争: 竞争条件 发生在多个 ...

  5. mysql 查询 锁表_怎么查找mysql中的锁表语句?

    查看sql server数据库被锁表可以用用如下语句: 也可以用如下语句: 拓展资料: 锁定数据库的一个表的区别SELECT * FROM table WITH (HOLDLOCK) 其他事务可以读取 ...

  6. mysql排他锁 升级_将共享升级到排他锁时避免MySQL死锁

    我使用MySQL 5.5.我注意到在并发情况下发生了特殊的僵局,我不认为这种僵局应该发生. 重现这样,使用两个同时运行的mysql客户端会话: mysql session 1: create tabl ...

  7. service层加需要加锁吗_面试官:了解乐观锁和悲观锁吗?

    为什么会使用到数据库级别的锁? 你可能会有这么一个疑问:现在的程序已经提供了很完善的锁机制来保证多线程的安全问题,还需要用到数据库级别的锁吗?我觉得还是需要的,为什么呢?理由很简单,我们再编程中使用的 ...

  8. redistemplate分布式锁实现_基于 Redis SETNX 实现分布式锁

    环境与配置 Redis 任意版本即可 SpringBoot 任意版本即可,但是需要依赖 spring-boot-starter-data-redis <dependency><gro ...

  9. python解除windows锁屏_实战 | Python批量提取Win10锁屏壁纸

    使用Win10的朋友会发现,每次开机锁屏界面都会有不一样的漂亮图片,这些图片通常选自优秀的摄影作品,十分精美. 但是由于系统会自动更换这些图片,所以就算再好看的图片,也许下次开机之后就被替换掉了. 借 ...

最新文章

  1. 5G UE — USIM Card — 5G 的 USIM 卡
  2. 自动转换开关(ATS)在数据中心配电系统中的应用
  3. Spring Boot集成Elastic Search
  4. 使用VS Code进行远程连接
  5. 路痴的单身小菡 BFS求最短路径+DFS求路径数
  6. SAP ABAP SteammPunk 蒸汽朋克的最新进展 - 嵌入式蒸汽朋克
  7. Form表单的主要Content-Type
  8. php ci model条件查询,php – CodeIgniter中的多条件WHERE子句
  9. 克隆需要验证_[实验技巧]CRISPR实验中如何验证编辑?
  10. Delphi 2009 之 TCategoryPanelGroup[5]: HeaderStyle
  11. linux内核的编译
  12. 秒杀系统优化方案之缓存、队列、锁设计思路
  13. Fedora下安装Nerolinux 4刻录软件
  14. windows server 2012显示桌面图标
  15. 哈德森喜迎万分夜 CBA“第一外援”就此易主?
  16. 计算机给文件重命名快捷键,计算机中文件重命名快捷键是什么
  17. php 英文小写变大写,PHP_PHP英文字母大小写转换函数小结,每个单词的首字母转换为大写 - phpStudy...
  18. Spring源码分析系列——bean创建过程分析(三)——工厂方法创建bean
  19. Vue组件自调用/无限递归导航/element-ui导航封装
  20. MATLAB数字图像处理练习六

热门文章

  1. Win10 WSL adb使用
  2. 电脑族每天宜喝四杯茶
  3. mount -o nolock
  4. tensorflow之lenet训练手写字及应用
  5. OpenGL——颜色混合 glBlendFunc函数
  6. linux 指定jvm djava.library.path_JVM命令
  7. python创建字符串_Python基础之字符串
  8. mysql 日期_「13」MySQL中与日期与时间相关的函数
  9. mysql 数据库导出导入到本地文件
  10. Android Studio实现简单的QQ应用