java process 中断_java-创建自中断ExecutorService

我有一个处理文件目录的任务,如果出现任何问题,则需要抛出IOException.我还需要它更快,所以我将完成的工作分成多个线程并等待它们终止.看起来像这样:

//Needs to throw IOException so the rest of the framework handles it properly.

public void process(File directory) throws IOException {

ExecutorService executorService =

new ThreadPoolExecutor(16, 16, Long.MAX_VALUE, TimeUnit.NANOSECONDS,

new LinkedBlockingQueue());

//Convenience class to walk over relevant file types.

Source source = new SourceImpl(directory);

while (source.hasNext()) {

File file = source.next();

executorService.execute(new Worker(file));

}

try {

executorService.shutdown();

executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);

} catch (InterruptedException e) {

executorService.shutdownNow();

throw new IOException("Worker thread had a problem!");

}

}

虽然Worker线程基本上是:

private class Worker implements Runnable {

private final File file;

public Worker(File file) { this.file = file; }

@Override

public void run() {

try {

//Do work

} catch (IOException e) {

Thread.currentThread().interrupt();

}

}

}

期望的行为是,如果任何Worker具有IOException,则使生成线程知道该异常,并且可以依次抛出其自己的IOException.这是我想到的允许Worker线程发出错误信号的最佳方法,但是我仍然不确定我是否将其设置正确.

那么,首先,这会符合我的期望吗?如果一个辅助线程在run()中有错误,将调用Thread.currentThread().interrupt();.是否导致引发InterruptedException,使其被阻塞的executorService.awaitTermination(Long.MAX_VALUE,TimeUnit.NANOSECONDS)捕获?

其次,如果正在运行的Worker在所有线程都已排队之前调用其中断,将会发生什么情况;在阻止try / catch块之前?

最后(也是最重要的一点),还有什么更优雅的方法可以实现我的目标?我希望所有无数子线程都执行到完成,或者直到其中任何一个出现错误为止,这时我想在生成线程中处理它(通过有效地使整个目录失败).

根据答案,这是我最终使用的实现.它很好地处理了我的异步需求,并且在IOExceptions上干净且相对快速地失败了.

public void process(File directory) throws IOException {

//Set up a thread pool of 16 to do work.

ExecutorService executorService = Executors.newFixedThreadPool(16);

//Arbitrary file source.

Source source = new SourceImpl(directory);

//List to hold references to all worker threads.

ArrayList> filesToWork =

new ArrayList>();

//Service to manage the running of the threads.

ExecutorCompletionService ecs =

new ExecutorCompletionService(executorService);

//Queue up all of the file worker threads.

while (source.hasNext())

filesToWork.add(new Worker(file));

//Store the potential results of each worker thread.

int n = filesToWork.size();

ArrayList> futures =

new ArrayList>(n);

//Prepare to return an arbitrary worker's exception.

IOException exception = null;

try {

//Add all workers to the ECS and Future collection.

for (Callable callable : filesToWork)

futures.add(ecs.submit(callable));

for (int i = 0; i < n; i++) {

try {

//Get each result as it's available, sometimes blocking.

IOException e = ecs.take().get();

//Stop if an exception is returned.

if (e != null) {

exception = e;

break;

}

//Also catch our own exceptions.

} catch (InterruptedException e) {

exception = new IOException(e);

break;

} catch (ExecutionException e) {

exception = new IOException(e);

break;

}

}

} finally {

//Stop any pending tasks if we broke early.

for (Future f : futures)

f.cancel(true);

//And kill all of the threads.

executorService.shutdownNow();

}

//If anything went wrong, it was preserved. Throw it now.

if (exception != null)

throw exception;

}

//Does work, and returns (not throws) an IOException object on error.

private class Worker implements Callable {

private final File file;

public Worker(File file) { this.file = file; }

@Override

public IOException call() {

try {

//Do work

} catch (IOException e) {

return e;

}

return null;

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值