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

时间:2018-04-28 18:53:22

标签: java multithreading concurrency threadpool

在我的课程中,我有一个名为" Vehicle"从Thread扩展,事情是,在某一点我需要这些线程来创建一个Task(Runnable),我希望所有这些任务都由同一个Threadpool管理,问题是如果我从一个不同的方法调用一个方法包含此Pool的类,每个其他线程正在创建一个不同的池。 我怎么能避免这个? 提前谢谢。

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

2 个答案:

答案 0 :(得分:2)

您的代码已使用单个线程池。但是,如果您的类可能有多个实例,并且您希望这些实例共享相同的线程池,则将其指定为静态变量。

虽然我现在也将关闭代码拉出到自己的方法中。也不要轮询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 :(得分:0)

两个选项:

  1. 您可以将ExecutorService对象声明为静态,或者:
  2. Station课程设为singleton
  3. 我建议阅读这篇文章: 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 https://stackoverflow.com/questions/1702386/is-threadpoolexecutor-thread-safe#answer-7596354
        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");
        }
    
    
    }