2015-06-29 3 views
3

Пожалуйста, помогите мне понять внутренний поток newFixedThreadPool (или Cached)Внутренняя обработка newFixedThreadPool

Когда мы пишем ниже утверждений, ExecutorService е = Executors.newFixedThreadPool (3);

  1. e.execute (runaable1);
  2. e.execute (runaable2);
  3. e.execute (runaable3);
  4. e.execute (runaable4);
  5. e.execute (runaable5);

до 3 выполнить методы, будут созданы три потока, когда будет вызываться 4-й метод выполнения, новый поток не будет создан, но работа будет ждать, пока поток станет бесплатным.

Я не понимаю этого момента «никакой новый поток не будет создан, но работа будет ждать, пока поток станет бесплатным». что я думаю, когда runnable1 будет предоставлен первому созданному потоку, как только будет запущен метод runnable1, запуск Thread1 также будет завершен, thread1 не сможет вызвать метод run runableable4. Итак, как java удается выполнить 5 Runnable только с тремя потоками.

ответ

3

FYI: Это очень простая реализация пула потоков.

class MyThreadPool implements java.util.concurrent.Executor 
{ 
    private final java.util.concurrent.BlockingQueue<Runnable> 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().run(); 
        } 
       } 
      }).start(); 
     } 
    } 

    @Override 
    public void execute(Runnable command) { 
     queue.put(command); 
    } 
} 

Это не будет компилироваться, потому что я не иметь дело с InterruptedException, и в пул потоков реального, вы также хотели бы иметь дело с исключениями, которые могут быть выброшены на данный command, но она должна дать вам общее представление о том, что делает пул потоков.

Создает очередь и произвольное число рабочих потоков. Рабочие потоки конкурируют друг с другом, чтобы потреблять команды из очереди. Очередь - BlockingQueue, поэтому рабочие все спят всякий раз, когда очередь пуста.

Другие потоки могут создавать новые команды (т. Е. Runnable объектов) и вызывать метод execute(command) для размещения новых команд в очереди. Команды будут выполняться (т. Е. Их методы запуска будут вызываться) рабочими потоками примерно * в том же порядке, в котором они были установлены в очередь.


  • Примерно, потому что работник может выбрать новую команду из очереди, а затем потерять его квант времени перед вызовом .run() метода выполнения команды. Другие работники могли затем выбирать другие команды из очереди и выполнять их до того, как планировщик позволит рабочему А снова запустить.
+0

+ 1'ed .. В чем преимущество такого подхода при использовании 'ExecutorService', который, если я прав, функционально одинаковый? – hagrawal

+0

@hagrawal, мой пример - это не подход к чему-либо, кроме обучения. Он предназначен только для иллюстрации того, кто может не понимать, что делает пул потоков. Я бы не использовал его как есть в любом реальном приложении, потому что ему не хватает многих полезных функций (обработка исключений, механизм выключения, фьючерсы и т. Д.), И не стоит тратить время на его улучшение, потому что классы в java. util.concurrent уже делает все, что мне обычно нужно. –

+0

любая подсказка/идея о том, как будет работать shutdown для этого? – krs8888

1

Когда вы выполните ExecutorService e=Executors.newFixedThreadPool(3);, пул потоков будет создан с тремя потоками внутри него. И эти 3 потока будут использованы для выполнения любой задачи, выполненной на вас e.

При попытке выполнить задачи через ExecutorService он будет добавлен в очередь задач, если количество потоков в пуле больше числа заданий, то, как только придет какая-то задача, некоторый свободный поток в пуле будут выбраны и использованы для выполнения задачи.

Когда количество задач становится больше, чем количество потоков в пуле, то они будут добавлены в pipleline в очереди, и как только какой-то поток будет завершен, этот поток будет использоваться для выполнения задачи из очереди очереди ,

пулы Тема:
Нить, который только что закончил не закончится. Просьба отметить, что это пул потоков, поэтому потоки объединяются, что означает, что они не будут завершены (как правило, до тех пор, пока у вас не будет некоторый тайм-аут или какой-либо другой механизм), но вернутся в пул, чтобы их можно было повторно использовать. И именно по этой причине ваши 4 и 5-го запуска будут выполняться через эти объединенные потоки.

"новая тема не будет создана, но работа будет ждать нить , чтобы быть бесплатной".

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

Ничего нового потока не будет создано, потому что вы использовали newFixedThreadPool, поэтому создан фиксированный пул потоков из 3 потоков, и они будут использоваться только для обработки всех запрошенных задач, поступающих в этот конкретный экземпляр ExecutorService, и в вашем случае это есть e.

Другие варианты резьбы бассейновой:
Вы можете создать пул потоков несколькими способами, используя java.util.concurrent.Executors. Например, используя Executors#newCachedThreadPool(), вы можете создать пул потоков, который при необходимости создает новые потоки, но будет использовать ранее созданные потоки, когда они будут доступны.
Проверьте все доступные способы найти наиболее подходящий вариант.

+0

Благодарим вас за ответ, я беспокоюсь здесь, если мы посмотрим на жизненный цикл Thread, new-> start-> runnable-> run -> (wait, sleep) -> runable-> run-> завершение, поэтому после выполнения первой задачи, в каком состоянии идет поток, я не думаю, что один и тот же поток после завершения выполнения (состояние завершения) можно снова использовать для другой задачи. – Nishat

+0

@ user872487, Каждый рабочий поток запускает цикл, выбирая новые задачи из очереди блокировки и запуская их. Цикл не выйдет, если вы не выключите исполнителя. –

+0

Нить, которая только что закончилась, не завершится. Просьба отметить, что это пул потоков, поэтому потоки объединяются, что означает, что они не будут завершены (как правило, до тех пор, пока у вас не будет некоторый тайм-аут или какой-либо другой механизм), но вернутся в пул, чтобы их можно было повторно использовать. И именно по этой причине ваши 4 и 5-го запуска будут выполняться через эти потоки. – hagrawal