漫画:怎么证明sleep不释放锁,而wait释放锁?

2f39ea55f4c94b2a487733fe8cb92a65.pnga34c9c2d2488d25bf9bc12d088c8af23.png9d242d77d58b01582bed409f90e9433b.png2de69618cdf502847dd10d221a1f0547.pnge2bb3e0f3c4cd2154225cb517c2e587a.png7a500e7f0aff21622e0a76c842206ca8.pnge7bdf94efe154d7d31c9e55d7a011fd3.png

wait 加锁示例

public class WaitDemo {private static Object locker = new Object();public static void main(String[] args) throws InterruptedException {WaitDemo waitDemo = new WaitDemo();// 启动新线程,防止主线程被休眠new Thread(() -> {try {waitDemo.doWait();} catch (InterruptedException e) {e.printStackTrace();}}).start();Thread.sleep(200); // 此行本身没有意义,是为了确保 wait() 先执行再执行 notify()waitDemo.doNotify();}/*** 执行 wait()*/private void doWait() throws InterruptedException {synchronized (locker) {System.out.println("wait start.");locker.wait();System.out.println("wait end.");}}/*** 执行 notify()*/private void doNotify() {synchronized (locker) {System.out.println("notify start.");locker.notify();System.out.println("notify end.");}}
}

以上程序的执行结果为:

wait start. 

notify start. 

notify end. 

wait end.

代码解析

从上述代码可以看出,我们给 wait() 和 notify() 两个方法上了同一把锁(locker),但在调用完 wait() 方法之后 locker 锁就被释放了,所以程序才能正常执行 notify() 的代码,因为是同一把锁,如果不释放锁的话,是不会执行 notify() 的代码的,这一点也可以从打印的结果中证实(结果输出顺序),所以综合以上情况来说 wait() 方法是释放锁的

sleep 加锁示例

public class WaitDemo {private static Object locker = new Object();public static void main(String[] args) throws InterruptedException {WaitDemo waitDemo = new WaitDemo();// 启动新线程,防止主线程被休眠new Thread(() -> {synchronized (locker) {try {System.out.println("sleep start.");Thread.sleep(1000);System.out.println("sleep end.");} catch (InterruptedException e) {e.printStackTrace();}}}).start();Thread.sleep(200);waitDemo.doNotify();}/*** 执行 notify()*/private void doNotify() {synchronized (locker) {System.out.println("notify start.");locker.notify();System.out.println("notify end.");}}
}

以上程序的执行结果为:

sleep start. 

sleep end. 

notify start. 

notify end.

代码解析

从上述代码可以看出 sleep(1000) 方法(行号:11)执行之后,调用 notify() 方法并没有获取到 locker 锁,从上述执行结果中可以看出,而是执行完 sleep(1000) 方法之后才执行的 notify() 方法,因此可以证明调用 sleep() 方法并不会释放锁

知识扩展

1.sleep 和 wait 有什么区别?

sleepwait 几乎是所有面试中必问的题,但想完全回答正确似乎没那么简单。

对于 sleepwait 的区别,通常的回答是这样的:

  • wait 必须搭配 synchronize 一起使用,而 sleep 不需要;

  • 进入 wait 状态的线程能够被 notify 和 notifyAll 线程唤醒,而 sleep 状态的线程不能被 notify 方法唤醒;

  • wait 通常有条件地执行,线程会一直处于 wait 状态,直到某个条件变为真,但是 sleep 仅仅让你的线程进入睡眠状态;

  • wait 方法会释放对象锁,但 sleep 方法不会。

但上面的回答显然遗漏了一个重要的区别,在调用 wait 方法之后,线程会变为 WATING 状态,而调用 sleep 方法之后,线程会变为 TIMED_WAITING 状态。

2.wait 能不能在 static 方法中使用?为什么?

不能,因为 wait 方法是实例方法(非 static 方法),因此不能在 static 中使用,源码如下:

public final void wait() throws InterruptedException {wait(0);
}

3.wait/notify 可以不搭配 synchronized 使用吗?为什么?

不行,因为不搭配 synchronized 使用的话程序会报错,如下图所示:898cc016ed6353a2ba80e71081214625.png

更深层次的原因是因为不加 synchronized 的话会造成 Lost Wake-Up Problem,唤醒丢失的问题,详情可见:https://juejin.im/post/5e6a4d8a6fb9a07cd80f36d1

总结

本文我们通过 synchronized 锁定同一对象,来测试 wait 和 sleep 方法,再通过执行结果的先后顺序证明:wait 方法会释放锁,而 sleep 方法并不会。同时我们还讲了几个 waitsleep 的常见面试问题,希望本文可以帮助到你。

3e9c813dd7e64218a9ad0a9c968e2506.gif

往期推荐

0d87213e46231e73538665a47ece7838.jpeg

Java 是值传递还是引用传递?


fcf820b3d1c84b78d8c456305c0502ba.jpeg

面试突击69:TCP 可靠吗?为什么?


efa0a0868baa2e335e6c1b35ffa7b80d.jpeg

面试突击66:请求转发和请求重定向有什么区别?


b2eb4527417de111b66a355769d0a49b.gif

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/544032.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

机器学习 导论_机器学习导论

机器学习 导论什么是机器学习? (What is Machine Learning?) Machine learning can be vaguely defined as a computers ability to learn without being explicitly programmed, this, however, is an older definition of machine learning. A more modern defin…

就国内某个程序员问答网站的简单的分析

为什么80%的码农都做不了架构师?>>> 一、数据抓取 分析页面数据,设计数据表结构数据只要包含投票、回答数、问题状态、最后谁回答过、浏览数、问题标题、标签,数据样例如下:由于一开只打算爬问题标题,问题…

树的结构 数据结构_段树| 数据结构

树的结构 数据结构What is a segment tree? 什么是段树? A segment tree is a full binary tree where each node represents an interval. A node may store one or more data members of an interval which can be queried later. 段树是完整的二叉树&#xff0…

iOS开发中 常用枚举和常用的一些运算符(易错总结)

1、色值的随机值:#define kColorValue arc4random_uniform(256)/255.0 // arc4random_uniform(256)/255.0; 求出0.0~1.0之间的数字view.backgroundColor [UIColor colorWithRed:kColorValue green: kColorValue blue: kColorValue alpha: 0.5]; 2、定时器的使用&…

明明加了唯一索引,为什么还是产生重复数据?

前段时间我踩过一个坑:在mysql8的一张innodb引擎的表中,加了唯一索引,但最后发现数据竟然还是重复了。到底怎么回事呢?本文通过一次踩坑经历,聊聊唯一索引,一些有意思的知识点。1.还原问题现场前段时间&…

python字符串 切片_用于切片字符串的Python程序

python字符串 切片Given a string and number of characters (N), we have to slice and print the starting N characters from the given string using python program. 给定一个字符串和字符数( N ),我们必须使用python程序从给定的字符串中切片并打印开始的N个字…

nmap入门之主机发现

2019独角兽企业重金招聘Python工程师标准>>> #主机发现(HOST DISCOVERY) ##仅列出IP,不扫描 nmap -sL 192.168.70.0/24 > nmap_result.txt 2>&1##仅ping扫描,不扫描端口 nmap -sn 192.168.70.0/24##不ping扫…

面试官:为什么ConcurrentHashMap要放弃分段锁?

今天我们来讨论一下一个比较经典的面试题就是 ConcurrentHashMap 为什么放弃使用了分段锁,这个面试题阿粉相信很多人肯定觉得有点头疼,因为很少有人在开发中去研究这块的内容,今天阿粉就来给大家讲一下这个 ConcurrentHashMap 为什么在 JDK8 …

ruby .each_Ruby中带有示例的Array.each方法

ruby .eachRuby Array.each方法 (Ruby Array.each method) Array.each method can be easily termed as a method which helps you to iterate over the Array. This method first processes the first element then goes on the second and the process keeps on going on unt…

面试突击72:输入URL之后会执行什么流程?

作者 | 磊哥来源 | Java面试真题解析(ID:aimianshi666)转载请联系授权(微信ID:GG_Stone)在浏览器中输入 URL 之后,它会执行以下几个流程:执行 DNS 域名解析;封装 HTTP 请…

二层交换网络_网络中的第2层交换

二层交换网络二层交换简介 (Introduction to Layer 2 Switching) As you know hubs are not intelligent devices. Whenever a hub receives a frame, it broadcasts the frame in all ports. Also, the hub represents a single collision domain i.e. when any 2 hosts send …

最小化托盘示例工程

http://files.cnblogs.com/files/kekec2/BuyTicket.rar.gif转载于:https://www.cnblogs.com/kekec2/p/4914572.html

面试必备:TCP 经典 15 连问!

TCP协议是大厂面试必问的知识点。整理了15道非常经典的TCP面试题,希望大家都找到理想的offer呀1. 讲下TCP三次握手流程开始客户端和服务器都处于CLOSED状态,然后服务端开始监听某个端口,进入LISTEN状态第一次握手(SYN1, seqx),发…

range函数python_range()函数以及Python中的示例

range函数pythonPython range()函数 (Python range() function) The range() is a built-in function in Python which returns the sequence of values. It is used where we need to perform a specific action for a limited number of times. In general, if we write rang…

ISP QoS Lab

ISP QoS Lab1-PQ优先级队列(PQ,Priority Queue)中,有高、中、普通、低优先级四个队列。数据包根据事先的定义放在不同的队列中,路由器按照高、中、普通、低顺序服务,只有高优先级的队列为空后才为中优先级的…

面渣逆袭:JVM经典五十问,这下面试稳了!

引言1.什么是JVM?JVM——Java虚拟机,它是Java实现平台无关性的基石。Java程序运行的时候,编译器将Java文件编译成平台无关的Java字节码文件(.class),接下来对应平台JVM对字节码文件进行解释,翻译成对应平台匹配的机器…

操作系统大内核和微内核_操作系统中的内核类型

操作系统大内核和微内核As we have already studied about the Kernels, we know that the Kernel is a program which is the main component of the Operating System. Now let us study about the types of Kernels. 正如我们已经研究了内核一样 ,我们知道内核是…

POJ 3268:Silver Cow Party 求单点的来回最短路径

Silver Cow PartyTime Limit: 2000MS Memory Limit: 65536KTotal Submissions: 15989 Accepted: 7303Description One cow from each of N farms (1 ≤ N ≤ 1000) conveniently numbered 1..N is going to attend the big cow party to be held at farm #X (1 ≤ X ≤ N). A t…

【论文解读】Learning based fast H.264 to H.265 transcoding

时间: 2015 年 级别:APSIPA 机构: 上海电力大学 摘要 新提出的视频编码标准HEVC (High Efficiency video coding)以其比H.264/AVC更好的编码效率,被工业界和学术界广泛接受和采用。在HEVC实现了约40%的编码效率提升的同时&#…

面试必备:聊聊sql优化的15个小技巧

sql优化是一个大家都比较关注的热门话题,无论你在面试,还是工作中,都很有可能会遇到。如果某天你负责的某个线上接口,出现了性能问题,需要做优化。那么你首先想到的很有可能是优化sql语句,因为它的改造成本…