作者热门文章
- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我想在有时间限制的后台执行一些工作。问题是,我不想阻塞主线程。
天真的实现是有两个执行器服务。一个负责安排/超时,第二个负责完成工作。
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 来清理任何其他资源。
关于java - ExecutorService超时而不阻塞主线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10333895/
有人可以向我澄清主线 DHT 规范中的声明吗? Upon inserting the first node into its routing table and when starting up th
我正在尝试使用 USB 小工具驱动程序使嵌入式设备作为 MTP 设备工作。 我知道 Android 从大容量存储设备切换到 MTP 设备已经有一段时间了,并且找到了 source code for M
我是一名优秀的程序员,十分优秀!