问题描述
|
调用带有超时值的联接并通过超时后,Java线程处于什么状态。因此,例如,您具有以下代码:
Thread thread = new Thread();
thread.start();
thread.join(TIMEOUT);
并且超时过去了,线程还没有返回什么状态?我需要注意些什么,以确保我不泄漏线程。我最初的假设是在加入调用之后执行如下操作:
if (thread.isAlive())
{
thread.interrupt();
thread = null;
}
要检查线程是否仍在运行,是否中断线程,然后将其清空以确保其已被垃圾回收。
解决方法
Javadoc指出join(time)函数将最多等待毫秒,直到线程死亡。实际上,如果超过了超时时间,您的代码将停止阻塞并继续执行。如果您担心这种情况下的“泄漏线程”,则可能应该重新设计,这样就不必加入线程并可以观察正在运行的线程的状态。此外,在线程上调用中断是不好的mojo。
class MyThread extends Thread {
private boolean keepRunning = true;
private String currentStatus = \"Not Running\";
public void run() {
currentStatus = \"Executing\"
while(keepRunning)
{
try {
someTask()
currentStatus = \"Done\";
} catch (Exception e) {
currentStatus = \"task failed\";
keepRunning = false;
}
}
}
public stopThread() {
keepRunning = false;
}
}
以上可能是处理线程的一个更好的例子。您无需将线程显式设置为null,但是例如,如果您将线程存储在ArrayList中,则将其从列表中删除,然后让Java处理。
,将连接与超时一起使用会有些危险。在某些情况下,即使我们超时,调用线程也将永远停留在join方法中。
参见http://insidecoffe.blogspot.com/2011/12/when-timeout-fails-in-threadjoin.html
, 并且超时过去了,线程还没有返回什么状态?
此时的线程状态是不确定的。您能说的最好的是它不会是新的,也可能不会被终止。 (但即使在后一种情况下,它也可能在触发超时和捕获超时异常的调用代码之间进入TERMINATED状态。)
关于此代码:
if (thread.isAlive()) {
thread.interrupt();
thread = null;
}
如果线程仍然存在,则可以保证传递中断。 (您极有可能尝试中断处于TERMINATED状态的线程,但是我对doc4ѭ的javadoc的阅读是,这是无害的。)
中断发生的事情完全取决于线程。具体来说,不能保证线程将看到中断或执行预期的操作。即完成。 (行为良好的线程应定期检查中断标志,并且不要挤压wait(...)
,sleep(...)
等上的“ interrupted \”异常)
将null
分配给thread
的影响将最小。如果线程仍在运行,则将不会对其进行垃圾回收。如果线程终止,则可能使“ 9”对象有资格进行垃圾回收。但这不会有太大的不同。当线程进入TERMINATED状态时,其堆栈会自动释放,将其从线程组中删除,并且指向to10ѭ的链接也为空。完成所有这些操作后,Thread对象将占用最少的内存:从存储泄漏的角度来看,无需担心。
,假设您正在检查中断(Thread.interrupted()和InterruptedException),我看不出为什么此方法不起作用。
在连接成功完成之后,我猜该线程可以在任何Thread.State中,但可以是NEW
,join
将使调用线程等待线程join
被调用而死亡,即完成执行。因此,示例中的thread
在超时到期时的状态将不是TERMINATED
(这就是为什么发生超时而不是join
返回\'natural \'的原因(在这种情况下thread
会处于why14ѭ状态) )-当然,在发生超时之后,thread
几乎可以立即转换为TERMINATED
状态)。
时间到期后,调用线程的状态将立即变为RUNNABLE,直到该时间为止,它将处于TIMED_WAITING
状态。