hen*_*lst 6 java scheduledexecutorservice
是否有一种内置方法可以取消Runnable已通过固定速率安排的任务ScheduledExecutorService.scheduleAtFixedRate并等待它完成(如果它在调用取消时碰巧正在运行)?
考虑以下示例:
public static void main(String[] args) throws InterruptedException, ExecutionException {
Runnable fiveSecondTask = new Runnable() {
@Override
public void run() {
System.out.println("5 second task started");
long finishTime = System.currentTimeMillis() + 5_000;
while (System.currentTimeMillis() < finishTime);
System.out.println("5 second task finished");
}
};
ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor();
ScheduledFuture<?> fut = exec.scheduleAtFixedRate(fiveSecondTask, 0, 1, TimeUnit.SECONDS);
Thread.sleep(1_000);
System.out.print("Cancelling task..");
fut.cancel(true);
System.out.println("done");
System.out.println("isCancelled : " + fut.isCancelled());
System.out.println("isDone : " + fut.isDone());
try {
fut.get();
System.out.println("get : didn't throw exception");
}
catch (CancellationException e) {
System.out.println("get : threw exception");
}
}
Run Code Online (Sandbox Code Playgroud)
这个程序的输出是:
5 second task started
Cancelling task..done
isCancelled : true
isDone : true
get : threw exception
5 second task finished
Run Code Online (Sandbox Code Playgroud)
设置一个共享的 volatile 标志似乎是最简单的选择,但如果可能的话,我更愿意避免它。
java.util.concurrent 框架是否内置了此功能?
我不完全确定你想要实现什么,但当我从谷歌搜索来到这里时,我认为可能值得回答你的问题。
1)如果你想强行停止繁重的工作负载 - 不幸的是,似乎没有解决方案(当线程不响应中断时)。处理它的唯一方法是在循环中的耗时操作之间插入 Thread.sleep(1) (http://docs.oracle.com/javase/1.5.0/docs/guide/misc/threadPrimitiveDeprecation.html) - 也许守护线程在这里会有所帮助,但我真的不鼓励使用它们。
2)如果您想阻止当前线程直到子线程完成,那么您可以使用 get http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Future.html而不是调用 cancel #get()甚至超时获取。
3)如果你想彻底取消子线程,那么你可以调用:
fut.cancel(false);
Run Code Online (Sandbox Code Playgroud)
这不会中断当前的执行,但不会安排它再次运行。
4)如果你的工作量不大,只需要等待5秒,那么使用线程睡眠或TimeUnit睡眠。在这种情况下,中断/取消将立即发生。
此外,您的示例缺少执行程序上的关闭调用,这会导致应用程序无法停止。
| 归档时间: |
|
| 查看次数: |
3040 次 |
| 最近记录: |