我想在有时间限制的后台执行一些工作。问题是,我不想阻塞主线程。
简单的实现是有两个执行器服务。一个负责安排/超时,第二个负责完成工作。
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<T> future = new FutureTask<T>(callable);
Thread thread = new Thread(future);
thread.start();
try {
future.get(120 * 1000, TimeUnit.MILLISECONDS);
} ...
上面代码片段中的可调用内容将是您的任务。
如果您有一个 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<T> future = new FutureTask<T>(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);
}
}
});
您不需要finally来关闭执行器。尽管您可能仍然需要一个finally来清理任何其他资源。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)