Java 我需要在这里检查Thread.isAlive()吗?
在web控制器中,我有一个接收请求的父线程。有些请求需要很长时间才能处理。为了防止客户端超时,我将父线程设置为在子线程执行操作的耗时部分时每2秒发送一个字节 我想确保我对所有可能发生的儿童线程死亡的情况进行了解释,但我也不想进行任何无关的检查 下面是父线程:Java 我需要在这里检查Thread.isAlive()吗?,java,multithreading,Java,Multithreading,在web控制器中,我有一个接收请求的父线程。有些请求需要很长时间才能处理。为了防止客户端超时,我将父线程设置为在子线程执行操作的耗时部分时每2秒发送一个字节 我想确保我对所有可能发生的儿童线程死亡的情况进行了解释,但我也不想进行任何无关的检查 下面是父线程: // This is my runnable class ProcessorRunnable runnable = new ProcessorRunnable(settings, Thread.currentThread()
// 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
我的问题是,添加&&Thread.isAlive()
检入父线程的主循环会给我带来什么好处吗?
似乎在
finally
块中设置done=true
应该可以做到这一点,但是在某些情况下,这个子线程可能会在不通知父线程的情况下死亡吗?子线程中的finally
总是在完成之前执行。即使该线程被中断或停止,这种情况也会通过一个异常发生,该异常会使调用堆栈冒泡并最终触发所有。因此,如果子线程被中断,done
将始终为真
对于此类后台任务,您可能希望使用ExecutorService
而不是原始线程。您可以将Runnable
提交给ExecutorService
,然后在返回的future上调用get()
,直到完成为止。如果您想在等待时打印空格,可以使用循环,在超时的情况下调用get()
版本。谢谢,我还将研究ExecutorService
。但是,对于原始线程解决方案,在到达try
语句之前是否会发生异常,从而导致最终
未被触发?@oksayt:在这种情况下,不会。在try
之前唯一的语句是对done
的赋值,它不能抛出。只能在非常特定的地方(等待、睡眠等)中断。从技术上讲,Thread.stop()
可能会这样做,但正是出于这个原因,它被弃用了。
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();
}
}