Обратите внимание, что не Executor
вызывает start()
- это ExecutorService
. И нет, он не звонит start()
дважды. Он не запускает задачу, которую вы передаете ему напрямую, используя Thread.start()
... вместо этого он запускает поток, который знает об очереди работы этого пула потоков. Поток, в основном, будет ждать выполнения некоторой работы, затем подхватит ее и выполнит, прежде чем вернуться к ожиданию. Таким образом, хотя поток выполняет несколько задач, Thread.start()
вызывается только один раз.
РЕДАКТИРОВАТЬ: Судя по комментариям, вы немного озадачены разницей между Runnable
(это задача, которая должна быть выполнена) и Thread
(это то, что выполняет задачи).
Один и тот же поток может выполнять несколько задач. Для очень простого примера, не использующего пул потоков, рассмотрим это:
public class MultiRunnable implements Runnable
{
private final List<Runnable> runnables;
public MultiRunnable(List<Runnable> runnables)
{
this.runnables = runnables;
}
public void run()
{
for (Runnable runnable : runnables)
{
runnable.run();
}
}
}
(Игнорировать потенциальные проблемы безопасности потоков при использовании List<T>
из нескольких потоков.)
Вы можете создать целую группу Runnable
задач, способных выполнять разные задачи, а затем создать одну MultiRunnable
, чтобы запускать их по очереди. Передайте этот экземпляр MultiRunnable
в конструктор Thread
, а затем при запуске потока он выполнит каждую из исходных выполняемых задач. Это помогает?