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作者也感到惊讶的错误》


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


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

 

目录
相关文章
|
1月前
|
安全 Java 编译器
一个 Bug JDK 居然改了十年?
你敢相信么一个简单的Bug,JDK 居然花了十年时间才修改完成。赶快来看看到底是个什么样的 Bug?
38 1
一个 Bug JDK 居然改了十年?
|
8月前
|
安全 easyexcel 数据库
Doug Lea大师的佳作CopyOnWriteArrayList,用不好能坑死你!
【5月更文挑战第14天】Doug Lea大师的佳作CopyOnWriteArrayList,用不好能坑死你!
57 4
|
缓存 Go
给大家丢脸了,用了三年golang,我还是没答对这道内存泄漏题。
给大家丢脸了,用了三年golang,我还是没答对这道内存泄漏题。
66 0
|
存储 编译器 C++
自写动态数组——参考《C++语言程序设计》(清华大学第4版)
自写动态数组——参考《C++语言程序设计》(清华大学第4版)
198 0
|
SQL 关系型数据库 MySQL
清华学姐熬了一个月肝出这份32W字Linux知识手册,在 Github标星31K+ 下
清华学姐熬了一个月肝出这份32W字Linux知识手册,在 Github标星31K+ 下
203 0
清华学姐熬了一个月肝出这份32W字Linux知识手册,在 Github标星31K+   下
|
运维 Ubuntu Linux
清华学姐熬了一个月肝出这份32W字Linux知识手册,在 Github标星31K+ 上
清华学姐熬了一个月肝出这份32W字Linux知识手册,在 Github标星31K+ 上
144 0
清华学姐熬了一个月肝出这份32W字Linux知识手册,在 Github标星31K+  上
|
缓存 搜索推荐 容灾
清华学姐熬了一个月肝出这份32W字Linux知识手册,在 Github标星31K+ 中
清华学姐熬了一个月肝出这份32W字Linux知识手册,在 Github标星31K+ 中
114 0
清华学姐熬了一个月肝出这份32W字Linux知识手册,在 Github标星31K+   中
Java小白翻身教程-链表结构与编译大法(1)
咳咳,我是小白,没错,主线剧情又回来了。现在我遇到麻烦了,老板要我设计一个类,可以用来保存多个客户的资料。
113 0
Java小白翻身教程-链表结构与编译大法(3)
D盘下面的tool文件夹已经有三个工具类了(其实是两个,CustNode是为了TuziLinkedList服务的),我们这一节来进行打包,这样的好处就是不用每次编译都把tool里面的类也带上了。
|
IDE Java 开发工具
Java小白翻身教程-链表结构与编译大法(4)
tools.jar是刚打出来的工具包,现在把它导入项目。

热门文章

最新文章