在具有超时的连接调用之后,Java线程会发生什么

时间:2011-04-14 01:47:50

标签: java multithreading

在使用超时值调用join并且超时超时后,Java线程处于什么状态。例如,您有以下代码:

Thread thread = new Thread();
thread.start();
thread.join(TIMEOUT);

并且超时传递并且线程没有返回状态是什么?我需要注意什么才能确保我不泄漏线程。我最初的假设是在加入调用之后做了类似的事情:

if (thread.isAlive())
{
   thread.interrupt();
   thread = null;
}

检查线程是否仍在运行,如果是,则中断它,然后将其清空以确保它被垃圾收集。

5 个答案:

答案 0 :(得分:5)

Javadoc声明join(time)函数最多会等待很多毫秒才能使线程死掉。实际上,如果超时通过,您的代码将停止阻塞并继续。如果你担心在这种情况下'泄漏线程',你可能应该重新设计,这样你就不必加入线程并且可以观察正在运行的线程的状态。此外,在线程上调用中断是坏事。

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处理它。

答案 1 :(得分:3)

使用超时加入会有一点危险。在某些情况下,调用线程将永远停留在join方法中,即使我们传递超时...

请参阅http://insidecoffe.blogspot.com/2011/12/when-timeout-fails-in-threadjoin.html

答案 2 :(得分:1)

  

并且超时传递并且线程没有返回状态是什么?

此时线程的状态是不确定的。你能说的最好的是它不会是新的,也可能不会被终止。 (但即使在后一种情况下,它也可能在已触发的超时和捕获超时异常的调用代码之间进入TERMINATED状态。)

关于此代码:

if (thread.isAlive()) {
   thread.interrupt();
   thread = null;
}

如果线程仍处于活动状态,那么可以保证传递中断。 (您尝试中断处于TERMINATED状态的线程的可能性很小,但我对interrupt()的javadoc的读取是无害的。)

中断的作用完全取决于线程。具体来说,不能保证线程会看到中断,或做出预期的事情;即完成。 (一个表现良好的线程应该定期检查中断的标志,并且不应该压缩wait(...)sleep(...)等上的“中断”例外。)

null分配给thread的影响微乎其微。如果线程仍在运行,它/它的资源无论如何都不会被垃圾收集。如果线程终止,则可能使Thread对象有资格进行垃圾回收。但这并没有多大区别。当一个线程进入TERMINATED状态时,它的堆栈将自动释放,它将从其线程组中删除,并且它与Runnable的链接将被清零。一旦完成所有操作,Thread对象占用的内存最少:从存储泄漏的角度来看,没有什么可担心的。

答案 3 :(得分:0)

join将导致调用线程等待线程join被调用,即死,即完成它的执行。因此,超时结束时示例中thread的状态将是TERMINATED的任何内容(这就是为什么超时发生而不是join自然返回的原因(在这种情况下thread将处于TERMINATED状态 - 当然,thread几乎可以在超时发生后立即转换到TERMINATED状态。

调用线程的状态将在时间到期后立即变为RUNNABLE,直到那时,它将处于TIMED_WAITING状态。

答案 4 :(得分:0)

假设您正在检查中断(Thread.interrupted()和InterruptedException),我看不出为什么这不起作用的原因。

连接成功后,我猜这个线程可以在任何Thread.State但是新