简体   繁体   English

Java线程中断和连接(连接后线程仍然存在)

[英]Java thread interrupts and joins (thread is still alive after join)

I'm trying to figure out some behavior. 我正在尝试找出一些行为。 I've got some code that spawns one thread. 我有一些生成一个线程的代码。 It waits some amount of time, and then interrupts it, joins it and then exits the method. 它等待一段时间,然后中断它,加入它,然后退出该方法。

.
.
.
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

I am currently running this with just one thread. 我目前仅使用一个线程运行此程序。 I can see in my logs that usually, isAlive() will be false after the join, but sometimes it is still alive. 我在日志中可以看到,通常,加入后isAlive()将为false,但有时它仍处于活动状态。 The thread is sitting in a while loop: 线程处于while循环中:

while(!Thread.currentThread().isInterrupted()){
.
// do some blocking io stuff here
}

So what I suspect is happening is we are interrupting the thread while it is reading/processing the inputstream (blocking io) and it is taking more than the time it takes to hit the while conditional and finish the join. 因此,我怀疑正在发生的事情是,我们在读取/处理输入流时阻塞了线程(阻塞io),花费的时间超过了有条件触发并完成连接所花费的时间。

So my question is, what happens to the thread? 所以我的问题是,线程发生了什么?

It is no longer referenced and the thread can be garbage collected, but none of of the resources are cleaned up properly, and that seems bad. 它不再被引用,线程可以被垃圾回收,但是没有正确清理所有资源,这似乎很糟糕。 Is there a better pattern for this besides switching to NIO? 除了切换到NIO,还有更好的模式吗?

interrupt() just sets a flag on the thread that it has been interrupted. interrupt()只是在已被中断的线程上设置一个标志。 Many blocking calls does not unblock when this occurs, meaning the thread is pretty much unaffected by the interrupt and keeps doing its thing(eg blocking on an InputStream). 发生这种情况时,许多阻塞调用不会解除阻塞,这意味着线程几乎不受中断的影响,并继续执行其工作(例如,在InputStream上进行阻塞)。

I'm guessing in some cases the thread doesn't unblock and hit your while condition in the given join timeout (1 second here), in other cases the blocking call happens to complete within the timeout and the thread ends. 我猜在某些情况下线程不会取消阻塞并在给定的连接超时(此处为1秒)内达到您的while条件,在其他情况下,阻塞调用恰好在超时内完成并且线程结束。

As long as a thread is running it will still have a reference and not be garbage collected. 只要线程正在运行,它仍将具有引用,并且不会被垃圾收集。 If the blocking call never unblocks - which could happen if it reads from eg a dead tcp sockets whos other end has silently disappeard, the thread might never end. 如果阻塞调用永远不会解除阻塞-如果它从死掉的tcp套接字读取消息,而另一端已经消失,则该线程可能永远不会结束。

除了“否”的答案,要中断阻塞的IO调用,您可以close()其流

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM