Java ExecutorService暂停/恢复特定线程

有没有办法使用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 tasks = new HashMap(); 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()

(如果你的工作线程在等待时被InterruptedException ,则acquire()方法抛出InterruptedException 。还有另一种方法acquireUninterruptibly() ,它也试图获取许可,但不会被中断。)