Вот некоторые детали:
import java.concurrent.Executors;
import java.concurrent.ExecutorService;
...
ExecutorService executor = Executors.newFixedThreadPool(someNumberOfThreads);
...
executor.execute(someObjectThatImplementsRunnable);
...
executor.shutdownNow();
Вот и все, что нужно сделать с помощью новых возможностей Java для многопоточности. Executor - это пул потоков с некоторым количеством NumberOfThreads. Питается блокирующей очередью. Все потоки спят, если нет работы. Когда вы помещаете объект Runnable в очередь с помощью метода execute (), объект Runnable остается в очереди до тех пор, пока не станет доступным поток для его обработки. Затем вызывается метод run (). Наконец, метод shutdownNow () сигнализирует о завершении всех потоков в пуле.
Теперь все намного проще, чем раньше.
(Существует множество вариаций, таких как пулы с минимальным и максимальным количеством потоков или очереди с максимальными размерами, прежде чем потоки, вызывающие execute (), будут блокироваться.)