Java线程中断和join(join后线程还活着)

发布于 2024-08-19 23:38:00 字数 1118 浏览 4 评论 0原文

我正在尝试找出一些行为。我有一些生成一个线程的代码。它等待一段时间,然后中断它,加入它,然后退出该方法。

.
.
.
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)时中断线程,并且它花费的时间超过了达到 while 条件并完成所需的时间加入。

所以我的问题是,线程会发生什么?

它不再被引用,并且线程可以被垃圾收集,但是没有任何资源被正确清理,这看起来很糟糕。除了切换到 NIO 之外,还有更好的模式吗?

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. The thread is sitting in a while loop:

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.

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

银河中√捞星星 2024-08-26 23:38:00

Interrupt() 只是在线程上设置一个标志,表明它已被中断。发生这种情况时,许多阻塞调用不会解除阻塞,这意味着线程几乎不受中断影响,并继续执行其操作(例如在输入流上阻塞)。

我猜测在某些情况下,线程不会在给定的连接超时(此处为 1 秒)内解锁并达到 while 条件,在其他情况下,阻塞调用恰好在超时内完成并且线程结束。

只要线程正在运行,它仍然会有一个引用并且不会被垃圾收集。
如果阻塞调用永远不会解除阻塞(如果它从另一端已悄然消失的死 TCP 套接字读取数据,则可能会发生这种情况),则线程可能永远不会结束。

interrupt() just sets a flag on the thread that it has been interrupted. Many blocking calls does not unblock when this occurs, meaning the thread is pretty much unaffected by the interrupt and keeps doing its thing(e.g. blocking on an 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.

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 e.g. a dead tcp sockets whos other end has silently disappeard, the thread might never end.

深海夜未眠 2024-08-26 23:38:00

除了 nos 的答案之外,要中断阻塞 IO 调用,您可以 close() 它的流

In addition to the nos's answer, to interrupt a blocking IO call you can close() its stream

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文