本文开始,将会以各种多线程相关的题目为基础,逐一进行分析,先开始从一个简单的例子开始。
问题剖析
题目:编号分别为 0 和 1 的线程,按照 ”偶数、奇数、偶数、奇数“ 的顺序输出结果,请严格确保输出顺序、线程能够正确退出。
方案如下,该方案有瑕疵,请谨慎阅读
1 | public class Solution { |
方案分析
该方案其实存在以下的一些问题
- 线程最后不会自动退出。最后一个线程执行 SolutionTask.class.notify() 后再执行 SolutionTask.class.wait(),因而线程一直在等待。
- 输出顺序不一定是 ”偶数、奇数“,有可能是 ”奇数、偶数“ 的情况,涉及到线程切换的问题。
解决方案
1 | public class Solution { |
处理类似问题的时候,也一定要对边界情况进行思考,特别是开始、结束部分,避免出现不符合题意的输出结果,类似于数据中的归纳法证明。
还有另外一点需要注意,线程共享变量 value 没必要使用 volatile 变量,原因是当线程被唤醒后再次通过 sychronized 获取互斥锁,sychronized 已经可以保证变量的可见性了。