最后阻塞在守护线程中
我知道守护线程中的finally 块不会被执行。但我细致的本性试图理解为什么 JVM 会发生如此特殊的情况,以至于它无法调用此块下的代码。
我认为它在某种程度上与调用堆栈有关,它不应该展开,但不知道如何展开。有人可以解释一下吗? 谢谢。
I know that finally blocks in deamon threads would not be executed. But my meticulous nature tries to understand why and what happens in JVM so special that it could not call the code under this block.
I think that it somehow related to call stack that it whould not unwind, but don't know how. Can someone please shed some light on this.
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
谁说守护线程中的
finally
块不会执行?一般来说,这不是正确的。您可能听说过,当 JVM 在
try
执行期间关闭时(或者catch
) 块。这是正确的(并且它很容易发生在守护线程上)。但同样:在正常操作期间,没有任何可以阻止
finally
块在守护线程中正常执行:它们没有以不同的方式处理。关闭问题很简单:当 JVM 被要求关闭甚至强制关闭时,它可能根本无法执行更多语句。
例如,在 POSIX-y 操作系统上,信号 9 (SIGKILL) 强制应用程序退出,使其没有机会进行任何清理(这就是通常首选信号 15 (SIGTERM) 的原因) 。在这种情况下,JVM 无法执行
finally
块,因为操作系统不会让它再运行。Who says that
finally
blocks in daemon threads don't execute? This is not true in general.What you might have heard that a
finally
block is not guaranteed to be executed when a JVM is shut down during the execution of thetry
(orcatch
) block. That is correct (and it can easily happen to daemon threads).But again: during normal operation, there is nothing that stops
finally
blocks from executing normally in daemon threads: they are not handled differently.The shutdown problem is easy: when the JVM is asked to shut down or even forced to shut down, then it may simply not be able to execute any more statements.
For example, on POSIX-y operating systems, signal 9 (SIGKILL) forces an application to quit, giving it no chance to do any cleanup (this is why signal 15 (SIGTERM) is preferred, usually). In this case, the JVM can't execute the
finally
block, because the OS won't let it run any longer.如果在执行 try 或 catch 代码时 JVM 退出,则finally 块可能不会执行。
正常关闭 - 当最后一个非守护进程时,会发生这种情况线程退出或当 Runtime.exit()
当线程退出时,JVM 会执行正在运行的线程的清单,并且如果唯一的线程剩下的是守护线程,它会启动有序关闭。当 JVM 停止时,任何剩余的守护线程都会被放弃,finally 块不会被执行,堆栈不会展开,JVM 只是退出。应谨慎使用守护线程,很少有处理活动可以随时安全地放弃,无需清理。特别是,将守护线程用于可能执行任何类型 I/O 的任务是危险的。守护线程最好保留用于“内务处理”任务,例如定期从内存缓存中删除过期条目的后台线程。
最后一个非守护线程退出示例:
输出:
If the JVM exits while the try or catch code is being executed, then the finally block may not execute.
Normal Shutdown - this occurs either when the last non-daemon thread exits OR when Runtime.exit()
When a thread exits, the JVM performs an inventory of running threads, and if the only threads that are left are daemon threads, it initiates an orderly shutdown. When the JVM halts, any remaining daemon threads are abandoned finally blocks are not executed, stacks are not unwound the JVM just exits. Daemon threads should be used sparingly few processing activities can be safely abandoned at any time with no cleanup. In particular, it is dangerous to use daemon threads for tasks that might perform any sort of I/O. Daemon threads are best saved for "housekeeping" tasks, such as a background thread that periodically removes expired entries from an in-memory cache.
Last non-daemon thread exits example:
Output:
我创建了两个非守护线程,它们将在其余两个守护线程之前终止。
一个非守护线程等待 20 秒,
一个守护线程等待 40 秒,
一个非守护线程休眠 15 秒,
一个守护线程休眠 30 秒,
一个守护线程休眠 10 秒。在一些守护线程之前终止非守护线程的想法。
结果表明,一旦没有非守护线程处于活动状态,JVM 将立即终止,而不执行守护线程的 Runnable 任务中的剩余语句,即使它们位于finally 块内且不会抛出 InterruptedException。
I have created two non-daemon threads which will terminate before the rest two daemon threads.
One non-daemon thread wait for 20 sec,
one daemon thread wait for 40 sec,
one non-daemon thread sleep for 15 sec,
one daemon thread sleep for 30 sec,
one daemon thread sleep for 10 sec. The idea to terminate non-daemon threads before some daemon ones.
As the result suggests, the JVM will terminate as soon as there is no non-daemon thread alive, without executing the rest statements in the Runnable tasks of the daemon threads, even if they are inside finally block without throwing InterruptedException.