有没有办法使用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个许可证( new Semaphore(1)
为每个任务,你需要暂停/取消暂停。 在任务的工作周期开始把这样的代码:
semaphore.acquire();
semaphore.release();
这使得获取信号量许可证,并立即释放它的任务。 现在,如果你要暂停的线程(按下按钮,例如),调用semaphore.acquire()
从另一个线程。 由于信号现在有0许可,您的工作线程将暂停在下一周期的开始,等到你叫semaphore.release()
从另一个线程。
(在acquire()
方法抛出InterruptedException
,如果你的工作线程被中断,而等待着。还有另一种方法acquireUninterruptibly()
它也试图获得许可,但不会被打断。)