此片段来自JCIP(Brian Goetz),列出6.15
f.get()抛出InterruptedException和ExecutionException。现在,这些例外是否具体到未来正确? 意味着未来所代表的特定任务被中断或有内部例外。
问题 -
为什么我需要使用“Thread.currentThread()。interrupt()”恢复中断? ,因为我的任务运行的线程不是中断标志?这有点令人困惑。
为什么要抛出washderThrowable异常?如果其中一个downloadImage有问题,我们难道只是处理从这里投掷的其他下载图像,因此只是“不”处理剩余的未来吗?
package net.jcip.examples;
import java.util.*;
import java.util.concurrent.*;
import static net.jcip.examples.LaunderThrowable.launderThrowable;
/**
* Renderer
* <p/>
* Using CompletionService to render page elements as they become available
*
* @author Brian Goetz and Tim Peierls
*/
public abstract class Renderer {
private final ExecutorService executor;
Renderer(ExecutorService executor) {
this.executor = executor;
}
void renderPage(CharSequence source) {
final List<ImageInfo> info = scanForImageInfo(source);
CompletionService<ImageData> completionService =
new ExecutorCompletionService<ImageData>(executor);
for (final ImageInfo imageInfo : info)
completionService.submit(new Callable<ImageData>() {
public ImageData call() {
return imageInfo.downloadImage();
}
});
renderText(source);
try {
for (int t = 0, n = info.size(); t < n; t++) {
Future<ImageData> f = completionService.take();
ImageData imageData = f.get();
renderImage(imageData);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} catch (ExecutionException e) {
throw launderThrowable(e.getCause());
}
}
interface ImageData {
}
interface ImageInfo {
ImageData downloadImage();
}
abstract void renderText(CharSequence s);
abstract List<ImageInfo> scanForImageInfo(CharSequence s);
abstract void renderImage(ImageData i);
}
答案 0 :(得分:3)
通过捕获InterruptedException
,您可以阻止中断到达正在运行的线程。但是你希望它能够达到它,以防万一中断时线程需要做任何特殊处理 - 你无法分辨,所以你最好安全地玩它并允许它渗透。你可以自己做一些处理(清理,退出你正在做的事情等),但你必须将它传递给你。最好的方法是拨打Thread.currentThread().interrupt()
。
答案 1 :(得分:3)
当您捕获InterruptedException时,中断标志会被重置,并且您的线程在技术上不会再被中断。但是,您不知道调用代码的代码(或同一线程中的其他代码)是否需要任何其他中断处理。通过调用interrupt(),你再次举起标志并有效地向应用程序的其余部分说“这个线程仍然被中断 - 必要时对它进行操作”。
考虑一下例子。如果线程被中断,则必须从循环中调用您的方法。您捕获了异常,如果您没有引发该标志,则循环将不会根据需要终止。
答案 2 :(得分:1)
中断不一定发生在线程池的线程上。当您等待未来的完成时,当前线程被中断时,中断是一个点。例如,如果您使Future可以访问可以取消下载的程序的另一部分,则Future.cancel(true)将导致发生InterruptedException,然后您可以清理其余的数据。正如Beohemaian所说,传播这种中断总是安全的。
这是个好问题。我认为这更像是他想要它做的设计选择。但是你可以很容易地抓住那个错误并在完成剩下的工作后抛出它。但要考虑一下,如果它是一个OutOfMemoryError怎么办?然后,只有当它出现错误并且可能不是RuntimeException时,清洗才有用。