Java8环境下Task2线程的for循环未执行问题排查
Task2循环不执行的成因与修正
直接触发原因:循环边界条件不成立
- Task2的run方法中,循环定义为
for(int k=beg; k<a; k++),循环能进入的唯一前提是起始值beg < 终止值a。 - 对应main方法中的赋值:
Task2.beg = one(Task1处理的元素总数)、Task2.a = two(Task2自身需要处理的元素总数)。只要输入的第一个整数one≥ 第二个整数two,循环起始值就会大于等于终止值,程序第一次判断循环条件就为false,直接跳过整个循环体,这就是你在循环内外加打印都看不到输出的根本原因。 - 举例:如果输入one=4,two=3,那么Task2的循环从k=4开始,判断4 < 3是否成立,直接不进入循环。
修正循环设计的根本问题
即便你调整输入让one < two,现有代码的逻辑依然无法通过题目校验:
- 循环范围不符合题目要求
题目要求Task2需要填充的数组区间是[one, one+two),也就是从Task1的结束位置开始,连续填充two个元素。但当前循环的终止条件是k < a(即k < two),当one>0时,实际填充区间是[one, two),既会漏填[two, one+two)的数组位置,也和Task1的填充范围不对齐。正确的循环终止条件应该写为k < beg + a,保证不管起始位置是多少,任务都会刚好填充a个元素。 - 共享资源的并发访问没有原子性保障
你现在让Task1、Task2并行运行时,两个线程会同时读写共享的Solution.i和threadArray,每一轮循环的操作是:读取Solution.i转成整数作为数组下标→给数组元素赋值→下标自增1→转回字符串写回Solution.i。这整段操作不是原子的,哪怕Solution.i加了volatile修饰,也只能保证多线程的可见性,解决不了并发时的“读-改-写”丢更新问题,最终会出现数组元素被覆盖、下标错乱,凑不出校验需要的连续序列。 - 解决并发错乱的方式:把每个任务里操作共享下标、数组的代码块,用
synchronized (Solution.class)加同一把类锁,保证同一时间只有一个线程在操作共享下标,避免竞态条件。
最终匹配题目校验的实现逻辑
修正后三个任务的填充范围需要完全连续无重叠:
- Task1:填充
[0, one)区间 - Task2:填充
[one, one+two)区间 - Task3:填充
[one+two, 300)区间
只要数组按照上述规则完成连续填充,就能满足题目中的三个校验条件:前one个元素包含Task2的起始值one、前one+two个元素不包含Task3的起始值one+two、Task3填充的区间和对应下标的值完全一致。
内容的提问来源于stack exchange,提问作者Veloxigami
相关产品推荐
相关产品推荐

