java - 让其他线程等到 ScheduledExecutorService 完成所有任务
问题描述
主要目标是使用 ScheduledExecutorService 运行一个方法,并等待其所有任务完成,然后再恢复主线程。
我在接受任何 Runnable 的自定义Scheduler类中创建了一个实用程序方法:
public void scheduleFunction(Runnable function) {
final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
final ScheduledFuture<?> producerHandle = scheduler.scheduleAtFixedRate(function, initialDelay, interval, MILLISECONDS);
scheduler.schedule(() -> { producerHandle.cancel(true); }, timeout, MILLISECONDS);
}
当我需要在计划模式下执行它的方法时,在其他类中使用它:
public void sendToKafka() {
Scheduler.scheduleFunction(this::produce);
}
这工作很好,除了一件事。当主线程到达sendToKafka()时,它调用调度程序来调度一个函数。主线程保持运行,同时调度功能开始工作。
预期结果:当调度程序线程启动时,主线程停止并等待调度程序完成执行
我怎样才能做到这一点?
解决方案
由于您在此方法中创建和放弃了一个ScheduledExecutorService
,因此您应该调用shutdown()
以支持及时释放资源。如果您这样做,您可以调用awaitTermination
以等待所有待处理作业的完成。
public void scheduleFunction(Runnable function) {
final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
final ScheduledFuture<?> producerHandle
= scheduler.scheduleAtFixedRate(function, initialDelay, interval, MILLISECONDS);
scheduler.schedule(() -> {
producerHandle.cancel(true);
scheduler.shutdown();
}, timeout, MILLISECONDS);
try {
scheduler.awaitTermination(Long.MAX_VALUE, MILLISECONDS);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
请注意,当您不需要中断时,您可以简单地使用
public void scheduleFunction(Runnable function) {
final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
scheduler.scheduleAtFixedRate(function, initialDelay, interval, MILLISECONDS);
scheduler.schedule(() -> scheduler.shutdown(), timeout, MILLISECONDS);
try {
scheduler.awaitTermination(Long.MAX_VALUE, MILLISECONDS);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
关闭ScheduledExecutorService
意味着停止重新安排工作;仅当正在进行执行时,它才会完成并awaitTermination
等待它。