验证Happen-Before规则时程序阻塞且无死锁问题求助
问题排查与解决
核心原因
程序阻塞的关键在于线程终止后其中断状态会被自动重置为false,结合主线程的循环逻辑导致无限等待:
- t1线程调用
t2.interrupt()后,t2的中断状态变为true,t2检测到该状态后退出循环并终止线程。 - 线程t2终止时,JVM会自动将其中断状态重置为false。
- 主线程的循环条件是
while(!t2.isInterrupted()),若主线程在t2终止后才检查其中断状态,会发现状态为false,从而陷入无限循环。
另外代码中x未被volatile修饰,存在可见性问题:主线程可能无法及时看到t1线程对x的赋值,不过这不是导致程序无法退出的直接原因,但会影响打印结果的正确性。
修复方案
要让主线程正确感知t2的结束,应该直接判断线程的存活状态,而非依赖中断状态:
static volatile int x; // 加volatile保证变量可见性 public static void main(String[] args) { Thread t2 = new Thread(()->{ while(true) { if(Thread.currentThread().isInterrupted()) { System.out.println(x); break; } } },"t2"); t2.start(); new Thread(()->{ try { Thread.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } x = 10; t2.interrupt(); },"t1").start(); // 改为判断线程是否存活 while(t2.isAlive()) { Thread.yield(); } System.out.println(x); }
补充说明
- 中断状态是线程的临时状态,线程终止后会被清除,不能用它来判断线程是否已经结束。
volatile关键字确保x的修改对所有线程可见,符合你验证Happen-Before规则的需求:t1线程对x的赋值操作Happen-Before于t2线程的读取,t1调用t2.interrupt()的操作Happen-Before于t2检测到中断,主线程等待t2结束后读取x,也能保证可见性。
内容的提问来源于stack exchange,提问作者dun mao
相关产品推荐
相关产品推荐

