2017-02-14 37 views
1

У меня есть следующий фрагмент кода:Как работают ExecutorService (int n) и Thread.activeCount()?

int k = 4; 

     ExecutorService e = Executors.newFixedThreadPool(k); 
     for (int i = 1; i <= k; i++) { 
      e.execute(new C(i)); 
      e.execute(new C(i)); 
     } 
     int active = Thread.activeCount(); 
     System.out.println(active); 
     e.shutdown(); 

Ясно видно, я представить два C каждой итерации цикла. В моем случае отправляются 8 C, хотя у ExecutorService установлен фиксированный размер 4. Это также подтверждается подсчетом активных потоков, которые равны 5.

Предполагается ли такое поведение? Я не понимаю, почему, по-видимому, только 4 новых потока запускаются и подсчитываются, в то время как 8 представлены. Я был бы очень рад, если бы кто-то смог прояснить концепцию ExecutorService и Thread.activeCount() для меня.

+0

* предназначено ли это поведение * Какое поведение? Что вы удивитесь? Какое поведение вы ожидаете? – shmosel

+0

@shmosel, если вы не знакомы с концессорными предложениями, я хотел бы направить вас следующим образом: http://dictionary.cambridge.org/dictionary/english/concessive-clause – blauerschluessel

+1

** В моем случае представлены 8 C, хотя ExecutorService имеет фиксированный размер 4 **, Executors.newFixedThreadPool (int), обрабатывает ПОСТОЯННО РАБОТАЮЩИЕ 4 РЕЗЬБЫ В ВРЕМЯ, и когда какой-либо поток заканчивает выполнение, те остальные 4 потока, которые были поставлены в очередь через e.execute (Runnable), будут в противном случае эти ДРУГИЕ 4 ОТ 8 потоков будут ждать завершения ДРУГОГО 4 ОТ 8 потоков, которые находятся в запущенном состоянии в пуле, ничто не должно удивлять, хотя – ShayHaned

ответ

3

Основная цель созданного ExecutorService - это пул потоков фиксированного размера (в вашем случае четыре потока). Если вы видите только четыре экземпляра Thread, созданных для ваших восьми частей работы, тогда он работает как разработанный.

Вы, кажется, думаете, что должно быть создано восемь потоков. Представьте, если вы подали миллион произведений; это было бы катастрофой, если бы был создан миллион потоков.

Абстракция позволяет вам контролировать, сколько потоков используется в одно время, независимо от количества элементов, которые необходимо обработать. ExecutorService рассматривает сложность повторного использования четырех потоков столько раз, сколько необходимо для обработки всех предметов, которые вы передаете, на вызовы execute.

Аналогия, которая может объяснить это банк. Вы создали банк с четырьмя счетчиками (четыре потока в пуле потоков) и восемь клиентов (восемь вызовов до execute) в строке. Когда кассир заканчивается с клиентом, следующий клиент в очереди обслуживается этим кассиром. Вы добавляете кого-то в очередь с вызовом execute, а ExecutorService управляет всем остальным. Вы контролируете количество потоков (счетчиков) по тому, как вы инициализируете ExecutorService (существует множество различных вкусов, которые вы можете создать).

+0

Отличный ответ! У меня есть предположение, что я читаю комментарии, но это подтверждает мои догадки. Однако теперь я нахожу другие интересные моменты: Например: где именно находятся клиенты? По аналогии, они, конечно, в банке, но где звонки? Как они хранятся, как их можно получить? Можно ли также манипулировать ими на полпути, может быть, почему приходят другие звонки? Как вы думаете, я должен открыть другой вопрос? – blauerschluessel

1

Я не понимаю, почему, по-видимому, только 4 новых потока запускаются и считаются, хотя 8 представлены.

Не путайте между нитями и задачами. Вы создали фиксированный ThreadPool для 4 потоков, и только 4 потока останутся в пуле.

Проверить выполнение Executors

/** 
    * Creates a thread pool that reuses a fixed number of threads 
    * operating off a shared unbounded queue. At any point, at most 
    * <tt>nThreads</tt> threads will be active processing tasks. 
    * If additional tasks are submitted when all threads are active, 
    * they will wait in the queue until a thread is available. 
    * If any thread terminates due to a failure during execution 
    * prior to shutdown, a new one will take its place if needed to 
    * execute subsequent tasks. The threads in the pool will exist 
    * until it is explicitly {@link ExecutorService#shutdown shutdown}. 
    * 
    * @param nThreads the number of threads in the pool 
    * @return the newly created thread pool 
    * @throws IllegalArgumentException if <tt>nThreads &lt;= 0</tt> 
    */ 
    public static ExecutorService newFixedThreadPool(int nThreads) { 
     return new ThreadPoolExecutor(nThreads, nThreads, 
             0L, TimeUnit.MILLISECONDS, 
             new LinkedBlockingQueue<Runnable>()); 
    } 

Вы можете найти более подробную информацию об отдельных параметрах ThreadPoolExecutor на официальной странице документации.

В вашем случае, число нитей 4. Количество заданий рабочих (которые осуществляют Runnable интерфейса) является 8.

Как они хранятся, как они могут быть доступны? Можно ли также манипулировать ими на полпути, может быть, почему приходят другие звонки?

  1. Задачи представляются в очереди задач (BlockingQueue)
  2. Если BlockingQueue полна (ограниченная очередь), политика Неприятие срабатывают.
  3. Если BlockingQueue не заполнен, рабочие задачи будут ждать, пока Thread их заберет.
  4. сообщения

Связанных SE:

How to properly use Java Executor?

Task getting rejected although threads are available

 Смежные вопросы

  • Нет связанных вопросов^_^