漫画:如何证明sleep不释放锁,而wait释放锁?

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 使用的话程序会报错,如下图所示:

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

总结

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

漫画:Integer 竟然有 4 种比较方法?


漫画:对象是如何被找到的?句柄 OR 直接指针?

关注下方二维码,每一天都有干货!

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

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

相关文章

设计模式 之 建造者

建造者模式(Builder Pattern) 一听这个名字,你可能就会猜到一二分了。建造者简单理解就是造东西,仅仅只是建造者模式建造的不是一个简单的东西,是一个比較复杂的东西。就好像盖房子,须要打地基、砌墙、灌…

stl string 函数_使用C ++ STL中的string :: append()函数将文本追加到字符串

stl string 函数append() is a library function of <string> header, it is used to append the extra characters/text in the string. append()是<string>标头的库函数&#xff0c;用于在字符串中附加多余的字符/文本。 Syntax: 句法&#xff1a; string&…

ABCDE类IP地址的解释

A类地址第1字节为网络地址&#xff0c;其它3个字节为主机地址。另外第1个字节的最高位固定为0。 A类地址范围&#xff1a;1.0.0.0到127.255.255.255。 A类地址中的私有地址和保留地址&#xff1a; 10.0.0.0到10.255.255.255是私有地址&#xff08;所谓的私有地址就是在互联网上…

身体健康小窍门

身体健康对于每个人来说都是第一重要的&#xff0c;找到的一些健康小窍门&#xff0c;可能有帮助&#xff1a; 1&#xff09;单鼻呼吸&#xff08; 来源 &#xff09;&#xff1a;中午以前最好常练习用左鼻子呼吸&#xff0c;没事的时候你就用手很自然的托住右边面颊&#xf…

支付宝上市,让我损失了2000万(盘点这些年错过的机会)

选择大于努力&#xff01;这句话在之前&#xff0c;我只是用排除法来解释它&#xff08;如果你的选择是错的&#xff0c;那么走的越快就离目标越远&#xff09;&#xff0c;而如今几次亲身的经历&#xff0c;却给了我不同的答案...近几天支付宝上市的事儿&#xff0c;传的沸沸扬…

(转)深入理解最强桌面地图控件GMAP.NET --- 原理篇

前几篇介绍了一些国内地图的案例&#xff0c; 深入理解最强桌面地图控件GMAP.NET --- SOSO地图 深入理解最强桌面地图控件GMAP.NET --- 百度地图 我们以Google地图为例,这章介绍下地图加载的原理。 投影(Projection) 谷歌地图采用的是墨卡托投影法,这里转载&#xff08;http://…

运算符sizeof_C程序通过使用sizeof()运算符对数组元素进行计数

运算符sizeofsizeof() operator returns the total number of size occupied by a variable, since array is also a variable, we can get the occupied size of array elements. sizeof()运算符返回变量占用的大小总数&#xff0c;由于array也是变量&#xff0c;我们可以获取…

查看 端口占用情况

“开始”-->“运行”-->“cmd”打开命令提示符&#xff0c;&#xff08;或win R&#xff09;输入“netstat -ano”可以看到所有的连接。可能的话&#xff0c;在“windows任务管理器”找到PID对应的程序即可。如果没有PID项&#xff0c;可以在“windows任务管理器”选“查…

LeetCode刷题--- 字母大小写全排列

个人主页&#xff1a;元清加油_【C】,【C语言】,【数据结构与算法】-CSDN博客 个人专栏 力扣递归算法题 http://t.csdnimg.cn/yUl2I 【C】 http://t.csdnimg.cn/6AbpV 数据结构与算法 http://t.csdnimg.cn/hKh2l 前言&#xff1a;这个专栏主要讲述递归递归、搜索与回…

4种分布式Session的实现方式!老大直呼666...

前言公司有一个 Web 管理系统&#xff0c;使用 Tomcat 进行部署。由于是后台管理系统&#xff0c;所有的网页都需要登录授权之后才能进行相应的操作。起初这个系统的用的人也不多&#xff0c;为了节省资源&#xff0c;这个系统仅仅只是单机部署。后来随着用的人越来越多&#x…

丘处机《摄生消息论》(转)

来源&#xff1a;http://www.qiuchuji.org/?typeshowtopic&id11 遗憾的是没有找到好的翻译版本&#xff0c;并且文中好像有些错别字&#xff0c;没有原文也没法对照修改。 春季摄生消息 春三月&#xff0c;此谓发陈&#xff0c;天地俱生&#xff0c;万物以荣。夜臥早起&…

InputStreamReader 和 OutputStreamWriter类使用方法简单介绍,及演示。

InputStreamReader 和 OutputStreamWriter类使用方法简单介绍。 一、InputStreamReader类 InputStreamReader 将字节流转换为字符流。是字节流通向字符流的桥梁。假设不指定字符集编码&#xff0c;该解码过程将使用平台默认的字符编码&#xff0c;如&#xff1a;GBK。 构造方法…

回溯算法n皇后问题_使用回溯算法的N Queen问题和解决方案

回溯算法n皇后问题N-皇后问题 (N - Queens problem) The n – queen problem is the generalized problem of 8-queens or 4 – queen’s problem. Here, the n – queens are placed on a n * n chess board, which means that the chessboard has n rows and n columns and t…

天气预报HTML代码

天气预报HTML代码<iframe height"200" src"http://weather.news.qq.com/inc/ss218.htm" frameborder"0" width"200" scrolling"no"></iframe><iframe width"420" scrolling"no" height&…

PHP源码安装及配置——以fastCGI的方式与httpd整合

在前一篇博文中介绍了LAMP的安装及配置。这里专门介绍PHP以fastCGI的方式与httpd整合的情况下&#xff0c;具体如何编译及配置。而且假定httpd、mysql均如前一篇博文介绍的安装配置完毕。php也采取一样版本的源码包php-5.6.1.tar.bz2。1. 编译安装php# tar xf php-5.6.1.tar.b…

超简单的分布式ID生成方案!美团开源框架介绍

目录阐述背景Leaf snowflake 模式介绍Leaf segment 模式介绍Leaf 改造支持 RPC阐述背景不吹嘘&#xff0c;不夸张&#xff0c;项目中用到 ID 生成的场景确实挺多。比如业务要做幂等的时候&#xff0c;如果没有合适的业务字段去做唯一标识&#xff0c;那就需要单独生成一个唯一的…

高质量的c源代码

现在自由软件及开源软件越来越流行&#xff0c;有大量的附带源程序的软件可以使用&#xff0c;这给我们学习软件开发提供了更多方便。但另一方面&#xff0c;也使得找到高质量的软件越来越不易。Landon Curt Noll 推荐 阅读David Ingalls Bell 的源代码。fefe 网站很推崇D.J.Be…

Java LinkedList公共布尔提供(对象o)方法(带示例)

LinkedList公共布尔提供(对象o)方法 (LinkedList public boolean offer(Object o) method) This method is available in package java.util.LinkedList.offer(Object o). 软件包java.util.LinkedList.offer(Object o)中提供了此方法。 This method is used to adds a specifie…

教你写Bug,常见的 OOM 异常分析

在《Java虚拟机规范》的规定里&#xff0c;除了程序计数器外&#xff0c;虚拟机内存的其他几个运行时区域都有发生 OutOfMemoryError 异常的可能。本篇主要包括如下 OOM 的介绍和示例&#xff1a;java.lang.StackOverflowErrorjava.lang.OutOfMemoryError: Java heap spacejava…

elf文件格式实例解析

试验环境&#xff1a;archlinux 速龙3000&#xff08;即x86兼容32位处理器&#xff09; 必须软件&#xff1a;gcc binutils 参考资料&#xff1a; System V application binary interface ELF Format &#xff08;mirror txt format ) Hello,world in less than 20 bytes…