Doug Lea在J.U.C包里面写的BUG又被网友发现了(5)

简介: Doug Lea在J.U.C包里面写的BUG又被网友发现了(5)

虚假唤醒


在 JDK 9 的注释里面还有这个词汇:


image.png


spurious wakeup,虚假唤醒。


如果你之前不知道这个东西的存在,那么恭喜你,又 get 到了一个你基本上用不到的知识点。


除非你自己需要在代码中用到 wait、notify 这样的方法。


哦,也不对,面试的时候可能会用到。


“虚假唤醒”是怎么一回事呢,我给你看个例子:


java.lang.Thread#join(long) 方法:


image.png


这里为什么要用 while 循环,而不是直接用 if 呢?


因为循环体内有调用 wait 方法。


为什么调用了 wait 方法就必须用 while 循环呢?


别问,问就是防止虚假唤醒。


看一下 wait 方法的 javadoc:


image.png


一个线程能在没有被通知、中断或超时的情况下唤醒,也即所谓的“虚假唤醒”,虽然这点在实践中很少发生,但是程序应该循环检测导致线程唤醒的条件,并在条件不满足的情况下继续等待,来防止虚假唤醒。


所以,建议写法是这样的:


image.png


在 join 方法中,isAlive 方法就是这里的 condition does not hold。


在《Effective Java》一书中也有提到“虚假唤醒”的地方:


image.png


书中的建议是:没有理由在新开发的代码中使用 wait、notify 方法,即使有,也应该是极少了,请多使用并发工具类。


再送你一个面试题:为什么 wait 方法必须放在 while 循环体内执行?


现在你能回答的上来这个问题了吧。


关于“虚假唤醒”就说这么多,有兴趣的同学可以再去仔细了解一下。


Netty的一个坑


好好的说着 JDK 的 FutureTask 呢,怎么突然转弯到 Netty 上了?


因为 Netty 里面,其核心的 Future 接口实现中,犯了一个基本的逻辑错误,在实现 cancel 和 isDone 方法时违反了 JDK 的约定。


这是一个让 Netty 作者也感到惊讶的错误。


先看看 JDK Future 接口中,对于 cancel 方法的说明:


https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Future.html


image.png


文档的方法说明上说:如果调用了 cancel 方法,那么再调用 isDone 将永远返回 true。


看一下这个测试代码:


image.png


可以看到,在调用了 cancel 方法后,再次调用 isDone 方法,返回的确实 false。


这个点我是很久之前在知乎的这篇文章上看到的,和本文讨论的内容有一点点相关度,我就又翻了出来,多说了一嘴。


有兴趣的可以看看:《一个让Netty作者也感到惊讶的错误》


好啦,才疏学浅,难免会有纰漏,如果你发现了错误的地方,可以在留言区提出来,我对其加以修改。


感谢您的阅读,我坚持原创,十分欢迎并感谢您的关注。

 

目录
相关文章
|
7月前
|
NoSQL Java Redis
阿里P8熬了一个月肝出这份32W字Java面试手册,在Github标星31K+
互联网行业竞争越来越严峻,面试也是越来越难,一直以来我都想整理一套完美的面试宝典,奈何难抽出时间,这套1000+道的Java面试手册我整理了整整1个月,上传到Git上目前star数达到了30K+
|
JavaScript 前端开发 Linux
2022 我用 MacBook Pro 整一年 【感想 与 踩坑指南】
2022 我用 MacBook Pro 整一年 【感想 与 踩坑指南】
249 0
|
运维 Ubuntu Linux
清华学姐熬了一个月肝出这份32W字Linux知识手册,在 Github标星31K+ 上
清华学姐熬了一个月肝出这份32W字Linux知识手册,在 Github标星31K+ 上
138 0
清华学姐熬了一个月肝出这份32W字Linux知识手册,在 Github标星31K+  上
|
SQL 关系型数据库 MySQL
清华学姐熬了一个月肝出这份32W字Linux知识手册,在 Github标星31K+ 下
清华学姐熬了一个月肝出这份32W字Linux知识手册,在 Github标星31K+ 下
194 0
清华学姐熬了一个月肝出这份32W字Linux知识手册,在 Github标星31K+   下
|
缓存 搜索推荐 容灾
清华学姐熬了一个月肝出这份32W字Linux知识手册,在 Github标星31K+ 中
清华学姐熬了一个月肝出这份32W字Linux知识手册,在 Github标星31K+ 中
106 0
清华学姐熬了一个月肝出这份32W字Linux知识手册,在 Github标星31K+   中
|
存储 消息中间件 安全
「避坑宝典」为大家分享一下笔者在 2022 年所遇到“匪夷所思”的 Bug 趣事(上)
「避坑宝典」为大家分享一下笔者在 2022 年所遇到“匪夷所思”的 Bug 趣事(上)
107 0
|
Java
Doug Lea在J.U.C包里面写的BUG又被网友发现了(4)
Doug Lea在J.U.C包里面写的BUG又被网友发现了(4)
224 0
Doug Lea在J.U.C包里面写的BUG又被网友发现了(4)
|
Java
Doug Lea在J.U.C包里面写的BUG又被网友发现了(3)
Doug Lea在J.U.C包里面写的BUG又被网友发现了(3)
265 0
Doug Lea在J.U.C包里面写的BUG又被网友发现了(3)
|
Java
Doug Lea在J.U.C包里面写的BUG又被网友发现了(1)
Doug Lea在J.U.C包里面写的BUG又被网友发现了(1)
134 0
Doug Lea在J.U.C包里面写的BUG又被网友发现了(1)
Doug Lea在J.U.C包里面写的BUG又被网友发现了(2)
Doug Lea在J.U.C包里面写的BUG又被网友发现了(2)
107 0
Doug Lea在J.U.C包里面写的BUG又被网友发现了(2)