关于 java 线程终止态时中断状态会被清空的现象

66 阅读2分钟

题目的背景是如何而来呢?我在调用 java 线程的 isInterrupted() 方法时,出现了一个下面的现象:

左图在中断线程thread并sleep 1 秒后,线程thread的中断状态并没有保留,右图在中断线程thread 1秒后,线程thread的中断状态则像 isInterrupted()方法支持的那样,中断状态保留了下来(因为调用interrupt()方法只是为线程打一个标识,并不是立刻中断线程,因此图1和图2我在中断线程之后、打印中断状态之前均执行了 Thread.sleep(1000))。而左图和右图的区别就在于线程重写的run()方法,即左图在线程被中断后方法会跳出、右图在线程被中断后方法不会跳出。

于是我就怀疑:线程终止后其中断状态会被清空。 当我去网上搜的时候,并没有搜到想要的回答,仅仅是在某AI问答下得到“线程终止后中断状态会保留”,可这与我遇到的现象不一致。因此我继续试验。

场景a.png场景b.png

下面左图中我注释了sleep(1000),这样中断线程后线程不一定会立刻终止,同时我在打印线程中断状态后紧接着打印线程生命周期,虽然这两条语句不是原子操作,但如果生命周期是终止态,那么该状态后续打印的中断状态如果都是false,那我的猜想可能就是正确的。右图可以看出,第一次打印中断状态是true,说明线程还在运行中,只是中断标识被更新了而已。继续看打印结果:生命周期RUNNABLE -> 中断状态 false,因为不是原子操作,所以不必理会。但当第一个生命周期“TERMINATED”出现后,后续所有的中断状态都为 false,此时基本可以断定终止态下的线程中断状态会被清空。

场景c.png 场景d.png

此外,我还发现线程的一个参数 eetop 可能具有某种含义。在网上我没有查到任何关于 eetop 的用法,都说是保留字段,但我发现,线程非终止态下eetop是有值的,而线程终止后并且调用interrupted()方法后,eetop会变为0。这或许是判断线程终止态的另一种方式,虽然可以直接调用thread.getState()查看,但目前看来eetop字段应该并不是简单的保留字段,而是有着一定的表示含义。

场景e.png 场景f.png

对于java多线程及其源码感兴趣的同学,欢迎与我交流,一起进步~

另外,上述只是我的个人见解,如描述有误,欢迎指出~