2014-12-15 3 views
0

Я пытаюсь понять многопоточность в Java. Я написал следующую java-программу для проверки пула потоков.Пул потоков Java: что происходит с простыми потоками

public class ThreadPoolTest 
{ 
    public static void main(String[] args) 
    { 
     ExecutorService executorService = Executors.newFixedThreadPool(5); 

     for(int i = 0; i < 3; i++) 
     { 
      executorService.submit(new Task(i+1)); 
     } 
     executorService.shutdown();      

    } 

    public static class Task implements Runnable 
    { 
     private int taskId; 

     public Task(int id) 
     { 
      taskId = id; 
     } 

     @Override 
     public void run() { 
      System.out.println("Executing task " + taskId + " performed by " + Thread.currentThread().getName()); 
      try 
      { 
       Thread.sleep(3000); 
      } 
      catch(InterruptedException interruptEx) 
      { 
       System.out.println(Thread.currentThread().getName() + " got interrupted "); 
      } 
      System.out.println("Finished executing task " + taskId); 
     } 
    } 
} 

Главный поток создает исполнитель, который создает 5 потоков, и я представил только 3 задания. После этого я закрываю исполнителя. Когда я запускаю код, основной поток заканчивается перед дочерними потоками. В этом случае JVM заботится о дочерних потоках? Также я создал пул потоков с 5 потоками, но представил только 3 задачи. Будут ли оставшиеся 2 потока прекращены при выходе основного потока?

Что происходит, когда служба-исполнитель выключается?

ответ

2

Рабочие потоки, которые создает исполнитель, являются внутренними классами, которые ссылаются на сам исполнитель. (Они нуждаются в нем, чтобы иметь возможность видеть очередь, runstate и т. Д.). Запуск потоков не является сборкой мусора, поэтому с каждым потоком в пуле, имеющим эту ссылку, они будут поддерживать исполнителя до тех пор, пока все потоки не будут мертвы. Если вы не вручную сделаете что-то, чтобы остановить потоки, они будут продолжать работать вечно, и ваша JVM никогда не отключится.

В случае 5 потоков, в которых заданы 3 задачи, 2 неиспользуемых потока никогда не будут запущены, но ссылки будут оставаться такими же, как и до выключения вызывается в finalize(), или все текущие потоки завершают выполнение.

Ниже приводится комментарий от JAVA Docs:

Пул, который больше не упоминается в программе и у него не осталось потоков не будет> автоматически выключился. Если вы хотите, чтобы освобожденные пулы были исправлены> даже если пользователи забыли вызвать shutdown(), тогда вы должны организовать, чтобы неиспользуемые потоки> в конечном итоге погибли, установив соответствующие временные интервалы хранения, используя нижнюю границу нулевого ядра> потоки и/или настройка allowCoreThreadTimeOut (логическое).

3

Из РОУ ExecutorService#shutdown():

Инициирует процедуру завершения работы, в которых ранее представленные задачи выполняется, но никакие новые задачи не будут приняты.

Это означает, что все рабочие места, который Вы представили Исполнитель финишируют свое время, не прерывая или «спешащий» их, и исполнитель завершит рабочие потоки правильно, но ни будет служба принимает новые рабочие места , и он не прекратится мгновенно.

Сравните ExecutorService#shutdownNow(), который попытается завершить как можно скорее.

1

В этом случае JVM заботится о дочерних потоках?

ОС управляет потоками и определяет, когда они запускаются.

Также я создал пул потоков с 5 потоками, но представил только 3 задания. Будут ли оставшиеся 2 потока прекращены при выходе основного потока?

Нет, потоки бегут, пока вы не закроете их.

Что на самом деле происходит при завершении службы исполнителя?

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

Когда последний неиспользуемый нить останавливает крюк выключения (если есть).

0

делает JVM заботится о ребенке нити

JVM только завершить выполнение после завершения всех тема демона. Если вы создаете своего как не-демона, он будет ждать завершения всех потоков не-демона.

Будет ли оставшиеся 2 нити прекращается, когда основной поток выходит

Нить будет создана в OnDemand режима. Так вот 3 нити создается только не 5.

Что на самом деле происходит, когда служба исполнителем является выключение

Initiates an orderly shutdown in which previously submitted tasks are executed, but no new tasks will be accepted. Invocation has no additional effect if already shut down. 
This method does not wait for previously submitted tasks to complete execution. Use awaitTermination to do that. 
Смежные вопросы