java - 如何覆盖 executorService 关闭方法

标签 java multithreading threadpool executorservice shutdown

我正在创建自己的线程池和可以并行执行可调用接口(interface)的 future 对象。 Executor 提供了 shutdown 方法来停止所有工作线程的运行。如果我正在创建如下所示的线程池,我应该如何实现关闭方法以在所有线程执行完毕后停止?

我的自定义线程池看起来像 this

class MyThreadPool implements java.util.concurrent.Executor 
{
    private final java.util.concurrent.BlockingQueue<Callable> queue;

    public MyThreadPool(int numThreads) {
        queue = new java.util.concurrent.LinkedBlockingQueue<>();
        for (int i=0 ; i<numThreads ; i++) {
            new Thread(new Runnable(){
                @Override
                public void run() {
                    while(true) {
                        queue.take().call();
                    }
                }
            }).start();
        }
    }

  @Override
  public <T> Future<T> submit(Callable<T> callable) {
    FutureTask<T> future = new FutureTask(callable);
    queue.put(future);
    return future;
  }

  public void shutdown(){ }
}

我想不出一种方法来保留线程列表,然后检查它们是否空闲?

最佳答案

您绝对应该持有对您正在创建的线程的引用。比如设置一个字段threads类型 List<Thread>并从构造函数中将线程添加到此列表。

之后,您可以实现 shutdown() Thread#join() 的帮助下:

public void shutdown() {
    for (Thread t : threads) {
        try {
            t.join();
        } catch (InterruptedException e) { /* NOP */ }
    }
}

不要忘记替换 while (true)具有适当的条件(您在 shutdown() 中切换)并考虑使用 BlockingQueue#poll(long, TimeUnit) 而不是 take() .

编辑:类似于:

public class MyThreadPool implements Executor {

    private List<Thread> threads = new ArrayList<>();
    private BlockingDeque<Callable> tasks = new LinkedBlockingDeque<>();
    private volatile boolean running = true;

    public MyThreadPool(int numberOfThreads) {
        for (int i = 0; i < numberOfThreads; i++) {
            Thread t = new Thread(() -> {
                while (running) {
                    try {
                        Callable c = tasks.poll(5L, TimeUnit.SECONDS);
                        if (c != null) {
                            c.call();
                        }
                    } catch (Exception e) { /* NOP */ }
                }
            });
            t.start();
            threads.add(t);
        }
    }

    public void shutdown() {
        running = false;
        for (Thread t : threads) {
            try {
                t.join();
            } catch (InterruptedException e) { /* NOP */ }
        }
    }

    // ...

}

关于java - 如何覆盖 executorService 关闭方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40064814/

相关文章:

java - 线程和jtable

java - 通过浏览器传送 csv 文件时出错

java - android java没有足够的顺序内存用于stringbuilder

c# - AutoResetEvent.WaitOne 超时与 Thread.Sleep

java - ThreadPoolTask​​Scheduler 不适用于线程池

java - 有了ThreadPoolExecutor,如何获取线程池中运行的线程名称?

java - java ThreadPool 中的取消函数 - 检测池中的特定可运行对象并将其取消

java - WebSphere 中的多个 Web 容器线程池 - 这可能吗?

java - 如何避免 FROM 子句中的子查询将 SQL 查询转换为 Hibernate 查询?

java - 当我尝试在 Activity 的 onCreate() 方法中设置不同的内容 View 时,为什么会出现此 RuntimeException?