是否可以使用ExecutorService暂停/恢复特定线程?
private static ExecutorService threadpool = Executors.newFixedThreadPool(5);
想象一下,我想以id = 0停止线程(假设每个线程都分配了一个增量ID,直到达到线程池的大小为止。)
过一会儿,通过按下一个按钮,我想恢复该特定线程,并让所有其他线程保持其当前状态,可以暂停或恢复。
我在Java文档中发现PausableThreadPoolExecutor的未完成版本。但这不适合我的需要,因为它可以恢复池中的所有线程。
如果无法使用ExecutorService的默认实现来做到这一点,谁能指出这个问题的Java实现吗?
谢谢!
您走错了路。线程池拥有线程,并且通过与代码共享它们可以使事情搞砸。您应该专注于执行任务(传递给可取消/可中断的线程),并且不要直接与池所拥有的线程进行交互。另外,在您尝试中断线程时,您将不知道正在执行什么作业,因此我看不到您为什么会对这样做感兴趣。
更新:
取消线程池中提交的任务的正确方法是通过执行者返回的任务的Future
。1)这样,您可以确定要取消的目标是实际要执行的任务2)如果您的任务已经被设计成可以取消的,那么您就完成了一半3)不要使用标志来表示取消,而应使用Thread.currentThread().interrupt()
代替更新:
public class InterruptableTasks {
private static class InterruptableTask implements Runnable{
Object o = new Object();
private volatile boolean suspended = false;
public void suspend(){
suspended = true;
}
public void resume(){
suspended = false;
synchronized (o) {
o.notifyAll();
}
}
@Override
public void run() {
while(!Thread.currentThread().isInterrupted()){
if(!suspended){
//Do work here
}
else{
//Has been suspended
try {
while(suspended){
synchronized(o){
o.wait();
}
}
}
catch (InterruptedException e) {
}
}
}
System.out.println("Cancelled");
}
}
/**
* @param args
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException {
ExecutorService threadPool = Executors.newCachedThreadPool();
InterruptableTask task = new InterruptableTask();
Map<Integer, InterruptableTask> tasks = new HashMap<Integer, InterruptableTask>();
tasks.put(1, task);
//add the tasks and their ids
Future<?> f = threadPool.submit(task);
TimeUnit.SECONDS.sleep(2);
InterruptableTask theTask = tasks.get(1);//get task by id
theTask.suspend();
TimeUnit.SECONDS.sleep(2);
theTask.resume();
TimeUnit.SECONDS.sleep(4);
threadPool.shutdownNow();
}
建议:与您所使用的标志类似/而不是所使用的标志,为您需要暂停/取消暂停的每个任务创建一个具有1个许可(semaphore)的new Semaphore(1)
。在任务的工作周期开始时,输入如下代码:
一种情况可能是,一个人想模拟许多设备。设备具有功能。这些设备集合总共可以同时运行。现在,如果一个线程代表一个设备(或一个线程代表一个设备的功能),则可能需要控制设备的生命周期,例如start(), shutdown(), resume()