问题描述
在中,它说的是 try {...} finally {...}
:
线程可以是 或被杀()这样,当运行此线程的JVM 不退出时, finally
块将不会执行杀? (我很困惑,因为上面引用的内容非常明确,误解的空间不大。)
Is it true that a thread can be interrupted or killed (I thought that was impossible?) such that the finally
block will not be executed while the JVM running this thread is not exited/killed? (I am puzzled because the quote above is pretty explicit about this, not much room for misunderstanding.)
编辑:将问题分解为其核心意图。
推荐答案
拉斐尔,我相信这是你所追求的优势之一。如果一个线程被本机阻塞(例如从 STDIN
或 Socket
读取),并且JVM在关闭状态,并且线程被中断,然后 finally
可能不会被调用。
Rafael, I believe this is one of the edge cases you are after. If a thread is blocked on something native (eg reading from STDIN
or a Socket
), and the JVM is in a state of shutdown, and the thread is interrupted, then finally
may not be invoked.
以下示例表明这一点不调用弃用方法:
The following example indicates this without invoking deprecated methods:
-
睡眠
- 最后 已调用。 -
SystemIn
- 最后未被调用。
Sleep
- finally is invoked.SystemIn
- finally is not invoked.
这个例子非常人为,仅供说明之用:)
The example is very contrived, and is purely provided for demonstrative purposes :)
public class Interrupted {
static final List<Thread> THREADS = Arrays.asList(
new Thread(new Sleep()),
new Thread(new SystemIn())
);
static final CountDownLatch LATCH = new CountDownLatch(THREADS.size());
public static void main(String[] args) throws Exception {
Runtime.getRuntime().addShutdownHook(new Thread(new ShutdownHook()));
for (Thread thread : THREADS) {
thread.start();
}
System.out.println("[main] Waiting for threads to start...");
LATCH.await();
System.out.println("[main] All started, time to exit");
System.exit(0);
}
static abstract class BlockingTask implements Runnable {
@Override
public void run() {
final String name = getClass().getSimpleName();
try {
LATCH.countDown();
System.out.printf("[%s] is about to block...%n",name);
blockingTask();
} catch (Throwable e) {
System.out.printf("[%s] ", name);
e.printStackTrace(System.out);
} finally {
System.out.printf("[%s] finally%n", name);
}
}
abstract void blockingTask() throws Throwable;
}
static class Sleep extends BlockingTask {
@Override
void blockingTask() throws Throwable {
Thread.sleep(60 * 60 * 1000); // 1 hour
}
}
static class SystemIn extends BlockingTask {
@Override
void blockingTask() throws Throwable {
System.in.read();
}
}
static class ShutdownHook implements Runnable {
@Override
public void run() {
System.out.println("[shutdown-hook] About to interrupt blocking tasks...");
for (Thread thread : THREADS) {
thread.interrupt();
}
System.out.println("[shutdown-hook] Interrupted");
try {
for (int i=0; i<10; i++) {
Thread.sleep(50L);
System.out.println("[shutdown-hook] Still exiting...");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
这篇关于当一个线程被中断/杀死时,最终块可能无法执行吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!