ExecutorService超时而不阻塞主线程

我想在有时间限制的后台执行一些工作。 问题是,我不想阻止主线程。

天真的实现是拥有两个执行者服务。 一个用于调度/超时,第二个用于完成工作。

final ExecutorService backgroundExecutor = Executors.newSingleThreadExecutor(); final ExecutorService workerExecutor = Executors.newCachedThreadExecutor(); backgroundExecutor.execute(new Runnable() { public void run() { Future future = workerExecutor.submit(new Runnable() { public void run() { // do work } }); try { future.get(120 * 1000, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { logger.error("InterruptedException while notifyTransactionStateChangeListeners()", e); future.cancel(true); } catch (ExecutionException e) { logger.error("ExecutionException", e); } catch (TimeoutException e) { logger.error("TimeoutException", e); future.cancel(true); } } }); 

还有其他解决方案吗?

您不需要ExecutorService就可以像这样一次运行一个线程。 您可以创建一个FutureTask,它可以在不增加开销的情况下为您提供相同的好处。

 FutureTask future = new FutureTask(callable); Thread thread = new Thread(future); thread.start(); try { future.get(120 * 1000, TimeUnit.MILLISECONDS); } ... 

上述代码段中的callable将是您的任务。 如果您有Runnable(就像在上面的代码块中那样),您可以通过以下方式将其转换为Callable:

 Callable callable = Executors.callable(runnable, null); 

总而言之,您的代码可能会更改为:

 backgroundExecutor.execute(new Runnable() { public void run() { Runnable myRunnable = new Runnable() { public void run() { // do work } } Callable callable = Executors.callable(myRunnable, null); FutureTask future = new FutureTask(callable); Thread thread = new Thread(future); thread.start(); try { future.get(120 * 1000, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { logger.error("InterruptedException while notifyTransactionStateChangeListeners()", e); future.cancel(true); } catch (ExecutionException e) { logger.error("ExecutionException", e); } catch (TimeoutException e) { logger.error("TimeoutException", e); future.cancel(true); } } }); 

你不需要最终关闭执行程序。 虽然您可能仍希望最终清理任何其他资源。