Ответ 1
Я думаю, что я понял, что вас пугает, так вот мой более длинный ответ: терминология - это крошечный бит, вводящий в заблуждение (очевидно, или вы не будете задавать этот вопрос, конкретно ставящий акцент на "повторное использование" ):
Как потоки потоков "повторно используют" потоки?
Что происходит, так это то, что один поток может использоваться для обработки нескольких задач (обычно передаваемых как Runnable
, но это зависит от вашей структуры "исполнителя": исполнители по умолчанию принимают Runnable
, но вы можете написать свой собственный "executor" /thread -pool принимает нечто более сложное, чем Runnable
[например, a CancellableRunnable
]).
Теперь в реализации по умолчанию ExecutorService
, если поток каким-то образом завершен во время использования, он автоматически заменяется новым потоком, но это не "повторное использование" , о котором они говорят. В этом случае "повторное использование" отсутствует.
Итак, правда, вы не можете дважды называть start()
в Java-потоке, но вы можете передать столько Runnable
, сколько хотите исполнителю, и каждый метод Runnable
run()
должен вызываться один раз.
Вы можете передать 30 Runnable
до 5 Java Thread
, и каждый рабочий поток может вызывать, например, run()
6 раз (практически не гарантирует, что вы будете выполнять ровно 6 Runnable
за Thread
но это деталь).
В этом примере start()
можно было бы назвать 6 раз. Каждый из этих 6 start()
будет вызывать ровно один раз метод run()
для каждого 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()
Runnable
, удалите следующий Runnable
(или блок) и запустите его метод run()
, затем промойте и повторите.
Я предполагаю, что часть путаницы (и это немного запутывает) происходит из-за того, что a Thread
принимает Runnable
и при вызове start()
вызывается метод Runnable run()
, тогда как пулы потоков по умолчанию также возьмите Runnable
.