Java ExecutorService暂停/恢复特定线程 [英] Java ExecutorService pause/resume a specific thread

查看:227
本文介绍了Java ExecutorService暂停/恢复特定线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Is there a way to use ExecutorService to pause/resume a specific thread?

private static ExecutorService threadpool = Executors.newFixedThreadPool ;

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

想象一下,我想停止线程,因为id = 0(假设给每个线程分配一个增量id,直到

Imagine that I want to stop the thread wich as the id=0 (assuming that to each one is assigned an incremental id until the size of the threadpool is reached).

过一段时间后,按下一个按钮,我想恢复该特定线程,并让所有其他线程与它们的当前

After a while, by pressing a button let's say, I want to resume that specific thread and leave all the other threads with their current status, which can be paused or resumed.

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

I have found on Java documentation a uncompleted version of PausableThreadPoolExecutor. But it doesn't suit what I need because it resume all the threads in the pool.

如果没有办法做与ExecutorService的默认实现可以任何人指向我的Java实现这个问题?

If there's no way to do it with the default implementation of the ExecutorService can anyone point me to a Java implementation for this problem?

谢谢!

推荐答案

p>你在错误的轨道上。线程池拥有线程,并通过与您的代码共享它们可能会搞乱。

您应该专注于使您的任务(传递到线程可取消/可中断),而不是与直接拥有的线程交互。

此外,你不知道在尝试中断线程时执行什么作业,所以我不明白为什么你会有兴趣做此

You are on the wrong track. The thread pool owns the threads and by sharing them with your code could mess things up.
You should focus on making your tasks (passed to the threads cancellable/interruptable) and not interact with the threads owned by the pool directly.
Additionally you would not know what job is being executed at the time you try to interrupt the thread, so I can't see why you would be interested in doing this

更新:

取消在线程池中提交的任务的正确方法是通过 Future 用于执行器返回的任务。

1)这样你就可以确定实际目标的任务试图被取消

2)如果你的任务已经被设计为可以取消,那么你的一半就在那里

3)不要使用标志来表示取消,而是使用 Thread.currentThread() .interrupt()而不是

Update:
The proper way to cancel your task submitted in the thread pool is via the Future for the task returned by the executor.
1)This way you know for sure that the task you actually aim at is attempted to be cancelled
2)If your tasks are already designed to be cancellable then your are half way there
3) Do not use a flag to indicate cancellation but use Thread.currentThread().interrupt() instead

更新

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();      
    }

这篇关于Java ExecutorService暂停/恢复特定线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆