Java ExecutorService暂停/恢复特定线程

问题描述 投票:10回答:3

是否可以使用ExecutorService暂停/恢复特定线程?

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

想象一下,我想以id = 0停止线程(假设每个线程都分配了一个增量ID,直到达到线程池的大小为止。)

过一会儿,通过按下一个按钮,我想恢复该特定线程,并让所有其他线程保持其当前状态,可以暂停或恢复。

我在Java文档中发现PausableThreadPoolExecutor的未完成版本。但这不适合我的需要,因为它可以恢复池中的所有线程。

如果无法使用ExecutorService的默认实现来做到这一点,谁能指出这个问题的Java实现吗?

谢谢!

java multithreading concurrency threadpool executorservice
3个回答
7
投票

您走错了路。线程池拥有线程,并且通过与代码共享它们可以使事情搞砸。您应该专注于执行任务(传递给可取消/可中断的线程),并且不要直接与池所拥有的线程进行交互。另外,在您尝试中断线程时,您将不知道正在执行什么作业,因此我看不到您为什么会对这样做感兴趣。

更新:

取消线程池中提交的任务的正确方法是通过执行者返回的任务的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();      
    }

4
投票

建议:与您所使用的标志类似/而不是所使用的标志,为您需要暂停/取消暂停的每个任务创建一个具有1个许可(semaphore)的new Semaphore(1)。在任务的工作周期开始时,输入如下代码:


0
投票

一种情况可能是,一个人想模拟许多设备。设备具有功能。这些设备集合总共可以同时运行。现在,如果一个线程代表一个设备(或一个线程代表一个设备的功能),则可能需要控制设备的生命周期,例如start(), shutdown(), resume()

© www.soinside.com 2019 - 2024. All rights reserved.