在 Web Controller 中,我有一个接收请求的父线程。有些请求需要很长时间才能处理。为了防止客户端超时,我将父线程设置为每 2 秒发回一个字节,而子线程正在执行操作的耗时部分。
我想确保我考虑到了子线程死亡的所有可能情况,但我也不想进行任何无关的检查。
这是父线程:
// This is my runnable class
ProcessorRunnable runnable = new ProcessorRunnable(settings, Thread.currentThread());
Thread childThread = new Thread(runnable);
childThread.start();
boolean interrupted = false;
while (!runnable.done) { // <-- Check in question
outputStream.write(' ');
outputStream.flush();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// If the runnable is done, then this was an expected interrupt
// Otherwise, remember the interruption and re-interrupt after processing is done
// Or with self so that a later expected interrupt won't clear out an earlier unexpected one
interrupted = interrupted || !runnable.done;
}
}
if (runnable.runtimeException != null) {
LOG.error("Propagating runtime exception from thread");
throw runnable.runtimeException;
}
// ... Further processing on the results provided by the child thread
这是 ProcessorRunnable:
private volatile boolean done;
private volatile Result result;
private volatile RuntimeException runtimeException;
// ...
public void run() {
done = false;
try {
result = myService.timeConsumingOperation(settings);
} catch (RuntimeException e) {
runtimeException = e;
} finally {
done = true;
parentThread.interrupt();
}
}
我的问题是,在父线程的主循环中添加 && Thread.isAlive()
检查会给我带来什么吗?
似乎在finally
block 中设置done = true
应该可以解决问题,但是在某些情况下,这个子线程可能会在不通知父线程的情况下死亡?
最佳答案
子线程中的finally
总是会在完成之前执行。即使该线程被中断或停止,也会通过异常导致调用堆栈冒泡并触发所有finally
。因此,如果子线程被中断,done
将始终为 true。
对于这样的后台任务,您可能需要使用 ExecutorService
而不是原始线程。您可以将 Runnable
提交给 ExecutorService
,然后只需对返回的 future 调用 get()
即可阻塞,直到完成为止。如果您想在等待时打印出空格,可以使用循环,调用带有超时的 get()
版本。
关于java - 我需要在这里检查 Thread.isAlive() 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8904680/