gpt4 book ai didi

java - 提交新任务时取消当前任务的 ExecutorService

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:20:36 27 4
gpt4 key购买 nike

考虑一个用户界面,它接受需要很长时间才能初始化的服务的配置设置(例如,JDBC 连接的参数)。我们希望我们的用户界面在服务初始化发生时保持响应。如果用户进行了其他更改,则应取消初始化并使用新参数重新启动。

因为当用户键入每个字符时参数被合并到配置中,所以可能会连续创建多个初始化请求。只有最后一个应该被执行。

我们已经将代码放在一起实现了这个结果,但看起来这种行为非常适合作为 ExecutorService 实现。在我们将所有内容重构为 ExecutorService 之前,我想我会问一下世界上是否已经有类似的实现。

更具体地说:

ExecutorService 将有一个工作线程。一旦提交了新任务,当前任务就会被取消(并且 worker 会被打断)。然后捕获新任务以供下一次执行。如果提交了另一个任务,则再次取消当前任务,并将“下次执行”任务设置为这个新任务。当工作线程最终选择执行下一个任务时,它将始终是最后提交的任务——所有其他任务要么被取消,要么被丢弃。

有没有人愿意分享这样的实现?或者是否有涵盖此类行为的标准库?实现起来并不难,但确定线程安全性可能很棘手,因此如果可以的话,我宁愿使用经过验证的代码。

最佳答案

这是我最终想出的 - 我对任何评论感兴趣:

public class InterruptingExecutorService extends ThreadPoolExecutor{
private volatile FutureTask<?> currentFuture;

public InterruptingExecutorService(boolean daemon) {
super(0, 1, 1000L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(),
daemon ? new DaemonThreadFactory() : Executors.defaultThreadFactory());

}

public static class DaemonThreadFactory implements ThreadFactory{
ThreadFactory delegate = Executors.defaultThreadFactory();

@Override
public Thread newThread(Runnable r) {
Thread t = delegate.newThread(r);
t.setDaemon(true);
return t;
}

}

private void cancelCurrentFuture(){
// cancel all pending tasks
Iterator<Runnable> it = getQueue().iterator();
while(it.hasNext()){
FutureTask<?> task = (FutureTask<?>)it.next();
task.cancel(true);
it.remove();
}

// cancel the current task
FutureTask<?> currentFuture = this.currentFuture;
if(currentFuture != null){
currentFuture.cancel(true);
}
}

@Override
public void execute(Runnable command) {
if (command == null) throw new NullPointerException();

cancelCurrentFuture();
if (!(command instanceof FutureTask)){ // we have to be able to cancel a task, so we have to wrap any non Future
command = newTaskFor(command, null);
}
super.execute(command);
}

@Override
protected void beforeExecute(Thread t, Runnable r) {
// it is safe to access currentFuture like this b/c we have limited the # of worker threads to only 1
// it isn't possible for currentFuture to be set by any other thread than the one calling this method
this.currentFuture = (FutureTask<?>)r;
}

@Override
protected void afterExecute(Runnable r, Throwable t) {
// it is safe to access currentFuture like this b/c we have limited the # of worker threads to only 1
// it isn't possible for currentFuture to be set by any other thread than the one calling this method
this.currentFuture = null;
}
}

关于java - 提交新任务时取消当前任务的 ExecutorService,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12966836/

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