Какое максимальное количество потоков создано в FixedThreadPool? - PullRequest
0 голосов
/ 05 мая 2018

Недавно мой наставник попросил меня реализовать свой собственный FixedThreadPool. В пуле должно быть не более N фиксированного числа потоков, выполняемых одновременно. У пула также будет механизм, при котором, если он заполнен, Runnables придется ждать, пока другие закончат работу. В Java, мы можем достичь этого с помощью -

ThreadPoolExecutor tpe = (ThreadPoolExecutor) Executors.newFixedThreadPool(3);
tpe.execute(t1);
tpe.execute(t2);
tpe.execute(t3);
tpe.execute(t4);

В моей реализации я всегда создаю объект new Thread и передаю ему входящие Runnables перед его запуском. Таким образом, общее количество потоков, которые я создаю (используя новое ключевое слово), всегда равно числу Runnables. Тем не менее, максимальное количество потоков в рабочем состоянии будет соответствовать N, установленному пользователем.

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

Но когда я вошел в реализацию ThreadPoolExecutor.execute в нативном коде Java, я обнаружил, что он создает новый объект для каждого Runnable, используя какую-то фабрику.

Снимок экрана из кода Java .

enter image description here

Теперь это как-то противоречит определению ThreadPool, в котором говорится, что потоки используются повторно. Пожалуйста, уточните это, так как мне трудно понять концепцию (которая необходима для правильной реализации моего пула).

P.S. Пожалуйста, извините мою плохую грамматику

Ответы [ 2 ]

0 голосов
/ 05 мая 2018

Это документ функции execute от java.util.concurrent.ThreadPoolExecutor

     /*
     * Proceed in 3 steps:
     *
     * 1. If fewer than corePoolSize threads are running, try to
     * start a new thread with the given command as its first
     * task.  The call to addWorker atomically checks runState and
     * workerCount, and so prevents false alarms that would add
     * threads when it shouldn't, by returning false.
     *
     * 2. If a task can be successfully queued, then we still need
     * to double-check whether we should have added a thread
     * (because existing ones died since last checking) or that
     * the pool shut down since entry into this method. So we
     * recheck state and if necessary roll back the enqueuing if
     * stopped, or start a new thread if there are none.
     *
     * 3. If we cannot queue task, then we try to add a new
     * thread.  If it fails, we know we are shut down or saturated
     * and so reject the task.
     */

Таким образом, в общем случае, если количество работающих потоков меньше corePoolSize или если старый поток умер, будет создан новый поток. В противном случае они помещаются в очередь (используя LinkedBlockingQueue)

0 голосов
/ 05 мая 2018

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

while (check if the pool is not shutdown) {
    Runnable task = pool.fetchTaskFromQueue(); // fetch the Task from the queue. In your case it object of MyRunnable class
    task.run(); // call the run() of MyRunnable object
}

Пул потоков продолжает реализацию Thread, а не Runnable/ Callable (класс Thread также является реализацией Runnable). Поэтому, если вы передаете объект Thread в ExecutorService#execute, он никогда не вызовет Thread#start для объекта потока, который вы отправили как argument из execute, он будет вызывать только Thread#run из ThreadPool's собственная тема.

Какое максимальное количество потоков создано в FixedThreadPool?

-> Максимальное количество потоков Тема в ThreadPool будет 3 согласно вашему коду.

...