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

这是why的第 69 篇原创文章
Doug Lea在J.U.C包里面写的BUG又被网友发现了文章插图
BUG描述一个编号为 8073704 的 JDK BUG , 将串联起我的这篇文章 。
也就是下面的这个链接 。
.java.net/browse/JDK-8073704
这个 BUG 在 JDK 9 版本中进行了修复 。 也就是说 , 如果你用的 JDK 8 , 也许会遇到这样的问题 。
先带大家看看这个问题是怎么样的:
Doug Lea在J.U.C包里面写的BUG又被网友发现了文章插图
这个 BUG 说:FutureTask.isDone 方法在任务还没有完成的时候就会返回 true 。
Doug Lea在J.U.C包里面写的BUG又被网友发现了文章插图
可以看到 , 这是一个 P4 级别(优先级不高)的 BUG , 这个 BUG 也是分配给了 Doug Lea , 因为 FutureTask 类就是他写的:
Doug Lea在J.U.C包里面写的BUG又被网友发现了文章插图
响应了国家政策:谁污染 , 谁治理 。
这个 BUG 的作者 Martin 老哥是这样描述的:
Doug Lea在J.U.C包里面写的BUG又被网友发现了文章插图
下面我会给大家翻译一下他要表达的东西 。
但是在翻译之前 , 我得先做好背景铺垫 , 以免有的朋友看了后一脸懵逼 。
如果要懂他在说什么 , 那我必须得再给你看个图片 , 这是 FutureTask 的文档描述:
Doug Lea在J.U.C包里面写的BUG又被网友发现了文章插图
看 Martin 老哥提交的 BUG 描述的时候 , 得对照着状态图和状态对应的数字来看 。
他说 FutureTask#isDone 方法现在是这样写的:
Doug Lea在J.U.C包里面写的BUG又被网友发现了文章插图
他觉得从源码来看 , 是只要当前状态不等于 NEW(即不等于0)则返回 true , 表示任务完成 。
Doug Lea在J.U.C包里面写的BUG又被网友发现了文章插图
他觉得应该是这样写:
Doug Lea在J.U.C包里面写的BUG又被网友发现了文章插图
这样写的目的是除了判断了 NEW 状态之外 , 还判断了两个中间状态:COMPLETING 和 INTERRUPTING 。
那么除去上面的三个状态之外呢 , 就只剩下了这四个状态:
Doug Lea在J.U.C包里面写的BUG又被网友发现了文章插图
这四个状态可以代表一个任务的最终状态 。
当然 , 他说上面的代码还有优化空间 , 比如下面这样 , 代码少了 , 但是理解起来也得多转个弯:
Doug Lea在J.U.C包里面写的BUG又被网友发现了文章插图
state>COMPLETING , 满足这个条件的状态只有下面这几种:
Doug Lea在J.U.C包里面写的BUG又被网友发现了文章插图
而这几种中 , 只有 INTERRUPTING 是一个中间态 , 所以他用后面的 != 排除掉了 。
这样就是代码简洁了 , 但是理解起来多转个小弯 。 但是这两段代码表示的含义是一模一样的 。
好了 , 关于这个 BUG 的描述就是这样的 。
汇总为一句话就是 , 这个 Martin 老哥认为:
FutureTask.isDone 方法在任务还没有完成的时候 , 比如还是 COMPLETING 和 INTERRUPTING 的时候就会返回 true , 这样是不对的 。 这就是 BUG 。
仅从 isDone 源码中那段 status != NEW 的代码 , 我认为这个 Martin 老哥说的确实没有问题 。 因为确实有两个中间态 , 这段源码中是没有考虑的 。