Java的ExecutorService的暂停/恢复特定线程(Java ExecutorServic

2019-06-26 23:35发布

有没有办法使用ExecutorService的暂停/恢复特定线程的方法吗?

private static ExecutorService threadpool = Executors.newFixedThreadPool(5);

想象,我想停止线程至极作为id = 0(假定每个之一被分配一个增量ID直到达到线程池的大小)。

一段时间后,通过按下一个按钮,让我们说,我想恢复的具体线索,并留下所有其他线程它们的当前状态,可以暂停或恢复。

我已经在Java文档中发现PausableThreadPoolExecutor的未完成版本。 但它不适合我的需要,因为它继续在池中的所有线程。

如果没有办法使用默认实施的ExecutorService的任何人都可以点我的Java实现了这个问题做呢?

谢谢!

Answer 1:

你是在错误的轨道上。 线程池拥有的线程,并通过与您的代码共享他们可能把事情搞得一团糟。
你应该集中精力使您的任务 (传递给线程撤销/可中断),而不是通过直接池拥有的线程交互。
此外,您不会不知道被你尝试中断线程时执行什么样的工作,所以我不明白为什么你有兴趣做这个

更新:
取消线程池中提交了任务,正确的方法是通过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();      
    }


Answer 2:

建议:类似于/而不是你所使用的标志,创建一个信号量与1个许可证( new Semaphore(1)为每个任务,你需要暂停/取消暂停。 在任务的工作周期开始把这样的代码:

semaphore.acquire();
semaphore.release();

这使得获取信号量许可证,并立即释放它的任务。 现在,如果你要暂停的线程(按下按钮,例如),调用semaphore.acquire()从另一个线程。 由于信号现在有0许可,您的工作线程将暂停在下一周期的开始,等到你叫semaphore.release()从另一个线程。

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



文章来源: Java ExecutorService pause/resume a specific thread