当前位置: 首页 > 知识库问答 >
问题:

Java Executor服务暂停/恢复特定线程

雍骏俊
2023-03-14

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

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

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

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

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

如果ExecutorService的默认实现无法解决这个问题,有人能给我介绍一个Java实现吗?

共有3个答案

杨凌
2023-03-14

一个场景可能是,一个想要模拟许多设备。设备有功能。总的来说,这组设备同时运行。现在,如果一个线程代表一个设备(或者一个线程代表一个设备的一个功能),那么可能需要控制设备的生命周期,比如start()、shutdown()、resume()

东方飞捷
2023-03-14

建议:与正在使用的标志类似,为每个需要暂停/取消暂停的任务创建一个带有1个许可证的信号量(新信号量(1))。在任务的工作周期开始时,输入如下代码

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

这会导致任务获取信号量许可证并立即释放它。现在,如果您想暂停线程(例如,按下一个按钮),请调用semaphore。从另一个线程获取()。由于信号量现在有0个许可证,您的工作线程将在下一个周期开始时暂停,并等待您调用信号量。从另一个线程释放()。

(如果工作线程在等待时被中断,acquire()方法将抛出InterruptedException)。还有另一种方法acquireUnterruptibly(),它也尝试获取许可证,但不会被打断。)

裴欣然
2023-03-14

你走错了路。线程池拥有这些线程,通过与代码共享它们,可能会把事情搞砸
您应该专注于使任务(传递给线程的任务是可取消/可中断的),而不是直接与池所拥有的线程交互
此外,当你试图中断线程时,你不知道正在执行什么作业,所以我不明白你为什么有兴趣这么做

更新:
取消您在线程池中提交的任务的正确方法是通过Future执行程序返回的任务。
1)这样您就可以确定您实际瞄准的任务正在尝试取消
2)如果您的任务已经设计为可取消的,那么您的任务已经完成了一半
3)不要使用标志来指示取消,而是使用Thread.currentThread()。中断()代替

更新:

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();      
    }
 类似资料:
  • 问题内容: 有没有一种方法可以使用ExecutorService暂停/恢复特定线程? 想象一下,我想停止id == 0的线程(假设为每个线程分配了一个增量ID,直到达到线程池的大小为止)。 过了一会儿,通过按下一个按钮,我想恢复该特定线程,并将所有其他线程保留为当前状态,这些状态可以暂停或恢复。 我在Java文档中发现了PausableThreadPoolExecutor的未完成版本。但这不适合我

  • 嗨,我在camel中有一个JMS消费者路由,我的要求是在特定事件时停止/暂停该路由(基于某个字段值),然后使用调度器恢复该路由。为此,我创建了两个路由,一个是我的原始jms消费者路由,另一个是调度程序路由,它们恢复jms消费者路由,虽然我能够暂停路由,但第二个路由不恢复暂停的路由,它显示的状态为已启动。 以下是我的两条路线 请帮助我如何实现上述场景。

  • 问题内容: 我声明我已阅读有关线程的内容,但从未使用过。所以我问你:) 我有两个线程:和,其中管理GUI和逻辑。 我将从开始。 然后在绘制GUI时,我将其暂停,以等待到达X点的run方法。 当到达X点进入run方法时,我暂停并继续。 并共享一些变量来管理GUI和逻辑… 我可以做吗?如果是,如何?:) 问题答案: 使用和方法: -使当前线程等待,直到另一个线程调用 该对象的方法。 -唤醒正在该对象的

  • 问题内容: 我有一个基本的Swing UI,带有一个标记为“播放”的按钮。按下按钮后,标签变为“暂停”。现在,当按下按钮时,它变为“继续”。 在“播放”中,我将实例化并执行一个SwingWorker。我想要的是能够暂停该线程(不要取消该线程),并根据上述按钮按下来恢复它。但是,我不想在doInBackground()中求助于Thread.sleep()。这似乎有点骇人听闻。有什么方法可以阻止运行d

  • 我要做的是暂停< code>KafkaConsumer,如果在使用消息的过程中出现错误。 这是我写的 然后我写了一个REST服务来恢复消费者 现在,我有两个问题。第一个问题:当我打电话给消费者时。来自<code>@KafkaListener</code>注释方法的pause()会发生什么?消费者立即暂停,或者我可以接收到同一主题分区的其他偏移量上的其他消息。例如,我有偏移量为3的“message1

  • 我们正在使用spring cloude stream 2.0 现在在Spring Cloud stream 2.0中,有一种使用执行器管理绑定器生命周期的方法:绑定可视化和控制 是否可以从代码控制绑定器的生命周期,这意味着在目标服务器关闭的情况下,绑定器,当它启动时,?