我想做一个2线程的应用程序,如下所示:
它不起作用了,有什么问题吗?
发布于 2018-09-07 11:48:43
问得好!我不认为你对awaitTermination()方法有一个清晰的理解。让我们来看看这个文档。
块,直到所有任务在关闭请求后完成执行,或超时发生,或当前线程被中断,以先发生者为准。
不应使用awaitTermination()来等待所有任务的完成。如果这是您要寻找的语义,则使用invokeAll()来阻止直到所有任务完成为止。不使用awaitTermination() 而不使用(以前的shutdown() )是不正确的,由于awaitTermination没有关闭执行器,可能会导致您等待一段时间。
在这种情况下,您只是试图强迫应用程序等待线程完成,但如果没有在分配的时间范围内,则需要继续。这个具体的案例让我有点怀疑多线程的使用,因为它看起来有点过于设计,但是为了教育的目的,让我们解释一下如何做到这一点。
基本解
ExecutorService executor = Executors.newFixedThreadPool(2);
executor.submit(() -> foo());
// Thread.sleep(2000); // Wait for 2 seconds
TimeUnit.SECONDS.sleep(2); // Also waits for 2 seconds and a bit more readable
executor.submit(() -> bar());
if (!executor.awaitTermination(20, TimeUnit.SECONDS))
executor.shutdownNow();虽然这不是理想的代码,但它将给您提供您正在寻找的语义。
改进
executor.submit()将返回一个Future<T>对象。这是Java中一个非常强大的对象,具有很多功能。让我们看看如何改进这个场景。
ExecutorService executor = Executors.newFixedThreadPool(2);
Future<T> foo = executor.submit(() -> foo());
T result = foo.get(2, TimeUnit.SECONDS); // Attempt to grab the result for 2 seconds, then move on
executor.submit(() -> bar());
if (!executor.awaitTermination(20, TimeUnit.SECONDS))
executor.shutdownNow();现在,这是更合适的代码,并将为您提供所需的语义和更好的代码结构。此外,如果第一个未来在2秒前完成,它将提前解除阻塞,这是对基本解决方案的一点改进!
适当关机
假设您想要等待20秒才能完成executor,下面是您可以做的额外改进。使用ExecutorService文档中的以下关闭代码作为关闭的示例。在这里,我已经更新了你的等待期为20秒。
pool.shutdown(); // Disable new tasks from being submitted
try {
// Wait a while for existing tasks to terminate
if (!pool.awaitTermination(20, TimeUnit.SECONDS)) {
pool.shutdownNow(); // Cancel currently executing tasks
// Wait a while for tasks to respond to being cancelled
if (!pool.awaitTermination(20, TimeUnit.SECONDS))
System.err.println("Pool did not terminate");
}
} catch (InterruptedException ie) {
// (Re-)Cancel if current thread also interrupted
pool.shutdownNow();
// Preserve interrupt status
Thread.currentThread().interrupt();
}发布于 2018-09-07 13:42:22
如何使用预定的执行者服务?您希望运行任务a,希望运行任务b,并希望在20秒后关闭executor服务。
ScheduledExecutorService service = Executors.newScheduledThreadPool(2);
Future<?> futureA = service.submit(()->foo());
ScheduledFuture<?> futureB = service.schedule(()->bar(), 2, TimeUnit.SECONDS);我不知道你为什么要关闭执行器,但是你可以利用未来等待任务的完成。
Object b = futureB.get(20, TimeUnit.SECONDS);
service.shutdown();https://stackoverflow.com/questions/52221501
复制相似问题