gpt4 book ai didi

java - 在执行器中从自身内部取消任务或超时后从外部取消

转载 作者:太空宇宙 更新时间:2023-11-04 06:45:52 26 4
gpt4 key购买 nike

好吧,我花了一些时间四处寻找,但未能找到明确的解决方案。我之前发布了一个单独的问题,但这是一个有点不同的问题。

问题:我想定期轮询是否发生某种情况。如果该条件仍然不成立,请再次重新安排。如果为 true,则停止调度。但我也只想等待一段确定的时间。这是我写的

 final ScheduledExecutorService service = Executors.newScheduledThreadPool(1);

final Future<?> future = service.schedule(new Runnable() {
@Override
public void run() {
if (conditionFalse()) {
System.out.println("its false. Rescheduling");
service.schedule(this, 2, TimeUnit.SECONDS);
} else {
System.out.println("true. Exiting");
}
}
}, 2, TimeUnit.SECONDS);

//Wait only for 5 seconds
future.get(5, TimeUnit.SECONDS); // does not work
//does not work either
service.schedule(new Runnable() {
@Override
public void run() {
future.cancel(true);
}
}, 5, TimeUnit.SECONDS);

这会不断重新安排自身,直到满足条件。关于为什么它不起作用有什么建议吗?如何只等待 5 秒然后停止任务执行?

最佳答案

Future.get 返回时,您的第一个任务已完成,但可能会使用相同的 Runnable 安排另一个任务。对第一个 Future 调用 cancel 不起作用,因为它代表第一个(已完成)任务,而不是新的计划任务。请记住,每次调用 schedule 都会返回一个新的 Future

最后不清楚为什么你要把这个任务搞得如此复杂。后台线程的一大优点是它们可以执行阻塞操作而不影响整个程序的执行。因此,如果您想每两秒重新检查一次条件,只需创建一个后台任务来实现每两秒检查一次的逻辑。等待两秒钟会阻塞该线程,但没关系,它是一个后台线程

ExecutorService service=Executors.newFixedThreadPool(1);
Future<?> f=service.submit(new Runnable() {
public void run() {
try {
while(conditionFalse()) {
System.out.println("it’s false, will wait");
Thread.sleep(TimeUnit.SECONDS.toMillis(2));
}
System.out.println("true. exiting.");
} catch(InterruptedException ex) {
System.out.println("interrupted. exiting.");
}
}
});
try {
try {
f.get(5, TimeUnit.SECONDS);
System.out.println("conditions met even before trying to cancel");
} catch(TimeoutException ex) {
System.out.println("canceling");
System.out.println(f.cancel(true)?
"canceled before conditions met": "conditions met before canceled");
}
} catch(InterruptedException | ExecutionException ex) {
throw new AssertionError(ex);
}

取消任务将立即结束 sleep ,这就是您的问题所在。只要不满足条件并且任务没有取消,就不需要重新安排;循环将继续运行。

如果任务较多,只需增加执行器的线程数即可。这可能感觉像资源消耗,但 sleep 线程不会消耗太多资源,并且 ScheduledExecutor 也会在任务执行之间保持一个 Thread sleep 。您甚至可以在不重新安排任务时节省一些操作。

重要的是代码是否清晰易懂,我认为简单的循环胜过(甚至不起作用)重新调度代码。

关于java - 在执行器中从自身内部取消任务或超时后从外部取消,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24005755/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com