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


接下来 , 我们就围绕着这个问题进行展开 , 看看各位大神的讨论 。
Doug Lea在J.U.C包里面写的BUG又被网友发现了文章插图
展开讨论首先 , 第一个发言的哥们是 Pardeep , 是在这个问题被提出的 13 天之后:
Doug Lea在J.U.C包里面写的BUG又被网友发现了文章插图
我没有太 get 到这个哥们回答的点是什么啊 。
他说:我们应该去看一下 isDone 方法的描述 。
Doug Lea在J.U.C包里面写的BUG又被网友发现了文章插图
描述上说:如果一个任务已完成 , 调用这个方法则返回true 。 而完成除了是正常完成外 , 还有可能是任务异常或者任务取消导致的完成 , 这些都算完成 。
我觉得他的这个回答和问题有点对不上号 , 感觉是答非所问 。
就当他抛出了一个关于 isDone 方法的知识点吧 。
Doug Lea在J.U.C包里面写的BUG又被网友发现了文章插图
三天后 , 第二个发言的哥们叫做 Paul , 他的观点是这样的:
Doug Lea在J.U.C包里面写的BUG又被网友发现了文章插图
首先 , 他说我们不需要检查 INTERRUPING 这个中间状态 。
因为如果一个任务处于这个状态 , 那么获取结果的时候一定是抛出 CancellationException 。
叫我们看看 isCancelled 方法和 get 方法 。
那我们先看看 isCancelled 方法:
Doug Lea在J.U.C包里面写的BUG又被网友发现了文章插图
直接判断了状态是否大于等于 CANCELLED , 也就是判断了状态是否是这三种中的一个:
Doug Lea在J.U.C包里面写的BUG又被网友发现了文章插图
判断任务是否取消(isCancelled)的时候 , 并没有对 INTERRUPING 这个中间状态做特殊处理 。
按照这个逻辑 , 那么判断任务是否完成(isDone)的时候 , 也不需要对 INTERRUPING 这个中间状态做特殊处理 。
接着 , 我们看看 get 方法 。
get 方法最终会调用这个 report 方法:
Doug Lea在J.U.C包里面写的BUG又被网友发现了文章插图
如果变量 s (即状态)是 INTERRUPING (值是 5) , 那么是大于 CANCELLED (值是 4)状态的 , 则抛出 CancellationException (CE)异常 。
所以 , 他觉得对于 INTERRUPING 状态没有必要进行检测 。
因为如果此状态下 , 你调用 isCancelled 方法 , 那么会告诉你任务取消了 。
如果你直接调用 get 方法 , 会抛出 CE 异常 。
所以 , 综上所述 , 我认为 Paul 这个哥们的逻辑是这样的:
我们作为使用者 , 最终都会调用 get 方法来获取结果 , 假设在调用 get 方法之前 。 我们用 isCancelled 或者 isDone 判断了一下任务的状态 。
如果当前状态好死不死的就是 INTERRUPING。 那么调用 isCancelled 返回 true , 那按照正常逻辑 , 是不会继续调用 get 方法的 。
如果调用的是 isDone, 那么也返回 true , 就会去调用 get 方法 。
在 get 方法这里保证了 , 就算当前处于 INTERRUPING 中间态 , 程序抛出 CE 异常就可以了 。
因此 , Paul 认为如果没有必要检测 INTERRUPING 状态的话 , 那么我们就可以把代码从:
Doug Lea在J.U.C包里面写的BUG又被网友发现了文章插图
简化为:
Doug Lea在J.U.C包里面写的BUG又被网友发现了文章插图


推荐阅读