повторное использование потока java
Я всегда читал, что создание потоков стоит дорого.
Я также знаю, что вы не можете перезапустить поток.
Я вижу в док Executors класс:
создает пул потоков, который создает потоки по мере необходимости, но будет повторно использовать ранее созданные потоки, когда они доступны.
запомните слово "повторное использование".
Как пулы потоков "повторно используют" потоки?
5 ответов:
я думаю, что понял, что вас смущает, поэтому вот мой более длинный ответ: терминология немного вводит в заблуждение (очевидно, или вы не зададите этот вопрос специально, сделав акцент на "повторном использовании"):
как пулы потоков "повторно используют" потоки?
происходит то, что один поток может быть использован для обработки нескольких задач (обычно передается как
Runnable, но это зависит от вашей структуры "исполнитель": исполнители по умолчанию принимаетRunnable, но вы можете написать свой собственный "исполнитель" / пул потоков, принимающий что-то более сложное, чем aRunnable[как, скажем, aCancellableRunnable]).теперь по умолчанию
ExecutorServiceреализация если поток каким-то образом прекращается во время использования, он автоматически заменяется новым потоком, но это не "повторное использование", о котором они говорят. В этом случае нет" повторного использования".так это правда, что вы не можете позвонить
start()на какой-нить Яве два раза но вы можете пройти столькоRunnableКак вы хотите, чтобы исполнитель и каждыйRunnable' srun()метод должен быть вызван один раз.вы можете пройти 30
Runnableдо 5 JavaThreadи каждый рабочий поток может вызывать, например,run()6 раз (практически нет гарантии, что вы будете выполнять ровно 6RunnableнаThreadно это деталь).start()был бы вызван 6 раз. Каждый из них эти 6start()позвоню только один раз therun()способ каждогоThread:С
Thread.start()Javadoc:* Causes this thread to begin execution; the Java Virtual Machine * calls the <code>run</code> method of this thread.но затем внутри каждого потока
run()методRunnableбудет снят с очереди иrun()способ каждогоRunnableбудет вызван. Таким образом, каждый поток может обрабатывать несколькоRunnable. Вот что они называют "повторное использование потоков".один из способов сделать свой собственный пул потоков-использовать блокирующую очередь на который вы ставите в очередь runnables и имеете каждый из ваших потоков, как только он закончит обработку
run()метод aRunnable, из следующегоRunnable(или блок) и запустить егоrun()метод, затем промыть и повторить.я думаю, что часть путаницы (и это немного запутанно) происходит от того, что a
ThreadпринимаетRunnableи после вызоваstart()Runnable ' srun()метод вызывается в то время как пул потоков по умолчанию и взятьRunnable.
The
runметод потоков в пуле потоков не состоит только из выполнения одной задачи. Элементrunметод потока в пуле потоков содержит цикл. Он вытаскивает задачу из очереди, выполняет задачу (которая возвращает назад к петле когда он будет завершен), а затем получает следующую задачу. Элементrunметод не завершается, пока поток больше не нужен.редактировать, чтобы добавить:
здесь
runметодWorkerвнутренний класс в ThreadPoolExecutor.696: /** 697: * Main run loop 698: */ 699: public void run() { 700: try { 701: Runnable task = firstTask; 702: firstTask = null; 703: while (task != null || (task = getTask()) != null) { 704: runTask(task); 705: task = null; // unnecessary but can help GC 706: } 707: } finally { 708: workerDone(this); 709: } 710: }
пул потоков состоит из нескольких фиксированных рабочих потоков, которые могут принимать задачи из внутренней очереди задач. Поэтому, если одна задача заканчивается, поток делает не конец, но ждет следующей задачи. Если прервать поток, он будет автоматически заменен.
посмотреть документация для более подробной информации.
пул потоков создает свои собственные потоки и предоставляет свои собственные умные маленькие Runnables для этих потоков. Эти Runnables никогда не заканчиваются, но синхронизируются в очереди (они ждут ()), пока вызываемый объект не будет присутствовать в этой очереди; они уведомляются, когда это происходит, и их Runnable запускает вызываемый объект из очереди, и весь сценарий повторяется снова.
Если
threadзакончено, конечно, можно использовать его снова. Вы можете убедиться, что он не работает, позвонивisAlive()или что-то подобное.EDIT : если кто-то приостановил
thread, нельзя начинать снова. Я не понимаю, почему он не может быть запущен, если он закончил нормально. Но я даю преимущество сомнения и говорю он не может быть использован повторно.
Comments