我正试图找出一些行为。我有一些代码可以产生一个线程。它会等待一段时间,然后中断它,加入它然后退出方法。
.
.
.
try {
Thread.sleep(processForMillis);
}
catch (InterruptedException ex) {
// Won't happen, ignore.
}
for (Thread t : threads) {
logger.debug("Interrupting Thread " + t.getName());
t.interrupt();
}
for (Thread t : threads) {
try {
t.join(1000L);
logger.debug("Joined Thread " + t.getName());
logger.debug("isAlive? " + t.isAlive());
}
catch (InterruptedException ex) {
// this will never happen
logger.debug("InterruptionException while joining, but didn't expect it.");
}
}
} // end of method
我目前只用一个线程运行它。我可以在我的日志中看到,通常,isAlive()在加入后将为false,但有时它仍然存在。线程处于while循环中:
while(!Thread.currentThread().isInterrupted()){
.
// do some blocking io stuff here
}
所以我怀疑正在发生的是我们在读取/处理输入流(阻塞io)时正在中断线程,并且它花费的时间超过了有条件并且完成连接所需的时间。
所以我的问题是,线程会发生什么?
它不再被引用,并且线程可以被垃圾收集,但没有一个资源被正确清理,这看起来很糟糕。除了切换到NIO之外,还有更好的模式吗?
答案 0 :(得分:1)
interrupt()只是在线程上设置了一个被中断的标志。发生这种情况时,许多阻塞调用都不会解除阻塞,这意味着线程几乎不受中断影响并继续执行其操作(例如阻塞InputStream)。
我猜测在某些情况下线程没有解除阻塞并在给定的连接超时(此处为1秒)内达到你的while条件,在其他情况下,阻塞调用恰好在超时内完成并且线程结束。 / p>
只要线程正在运行,它仍然会有一个引用而不是垃圾回收。 如果阻塞调用永远不会解除阻塞 - 如果它从例如一个死的tcp套接字,其他端已经默默地消失,线程可能永远不会结束。
答案 1 :(得分:0)
除了nos的答案,要中断阻塞IO调用,您可以close()
其流