如何避免每个线程创建不同的池?

How can I avoid that each Thread creates a different pool?

在我的程序中,我有一个名为 "Vehicle" 的 class,它从 Thread 扩展而来,问题是在某个时候我需要这些线程来创建一个任务(可运行),我想要所有这些任务由同一个线程池管理,问题是如果我从包含此池的不同 class 调用方法,则每个其他线程都会创建一个不同的池。 我怎样才能避免这种情况? 提前致谢。

public class Station {
    Arrivals arrivals;
    Vehicle k;
    ListPumps lp;

    ExecutorService executor = Executors.newFixedThreadPool(3);
    public synchronized void startWork(Pump p) {

        Runnable w = new Work(p);
        executor.execute(w);

        executor.shutdown();
        while (!executor.isTerminated()) {
    }
        System.out.println("Finished all threads");
     }
}

您的代码已经使用了一个线程池。但是,如果您的 class 可能有多个实例,并且您希望它们共享同一个线程池,则将其分配为静态变量。

虽然我现在也会将关闭代码提取到它自己的方法中。也不要轮询 isTerminated,使用 awaitTermination。

类似于以下内容:

public class Station {

    private Arrivals arrivals;
    private Vehicle k;
    private ListPumps lp;

    private static ExecutorService executor = Executors.newFixedThreadPool(3);

    public void startWork(Pump p) {
        Runnable w = new Work(p);
        executor.execute(w);
    }

    public static synchronized void shutdown() {
        executor.shutdown();
        if(executor.awaitTermination(60, TimeUnit.SECONDS))
            System.out.println("Finished all threads");
        else
            System.out.println("Executor shutdown timed out");
    }
}

两个选项:

  1. 您可以将 ExecutorService 对象声明为静态对象,或者:
  2. 创建 Station class 为 singleton

我推荐阅读这篇文章 post: should ExecutorService be static and global

public class Station {

    private Arrivals arrivals;
    private Vehicle k;
    private ListPumps lp;

    // Bill Pugh Singleton Implementation
    private static class ExecutorServiceHelper {

        // volatile keyword to avoid CPU caching EXECUTOR object
        // famous volatile illutration http://tutorials.jenkov.com/images/java-concurrency/java-volatile-2.png
        private static volatile ExecutorService EXECUTOR = Executors
                .newFixedThreadPool(3);;

    }

    public ExecutorService getInstance() {
        return ExecutorServiceHelper.EXECUTOR;
    }

    // implementation of executor framework is threadsafe, so you don't need 
    // to use synchronized keyword on methods calling executors methods
    // here is the discussion 
    public void submitWork(Pump p) {
        Runnable w = new Work(p);
        getInstance().execute(w);
    }

    public void shutdown() {
        getInstance().shutdown();
        if(getInstance().awaitTermination(60, TimeUnit.SECONDS))
            System.out.println("Finished all threads");
        else
            System.out.println("Executor shutdown timed out");
    }


}