Как я могу избежать того, что каждый поток создает отдельный пул? - PullRequest
0 голосов
/ 28 апреля 2018

В моей программе у меня есть класс «Vehicle», который происходит от Thread, дело в том, что в определенный момент мне нужны эти Threads для создания задачи (Runnable), и я хочу, чтобы все эти задачи управлялись одним и тем же Проблема заключается в том, что если я вызываю метод из другого класса, который содержит этот пул, каждый другой поток создает другой пул. Как я могу избежать этого? Заранее спасибо.

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 голосов
/ 28 апреля 2018

Два варианта:

  1. Вы можете объявить ExecutorService объект как статический, или:
  2. Создать Station класс как singleton

Я рекомендую прочитать это сообщение: должен ExecutorService быть статическим и глобальным

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 /858958/yavlyaetsya-li-executorservice-v-chastnosti-threadpoolexecutor-bezopasnymanswer-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");
    }


}
0 голосов
/ 28 апреля 2018

Ваш код уже использует один пул потоков. Однако если у вашего класса может быть несколько экземпляров, и вы хотите, чтобы все они совместно использовали один и тот же пул потоков, назначьте его в качестве статической переменной.

Хотя я бы тоже сейчас вытащил код завершения работы для его собственного метода. Также не опрашивайте isTermination, используйте 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");
    }
}
...