Как повторно использовать поток в Java?
Я являюсь зданием консоли Sudoku Solver, где основной целью является скорость raw.
Теперь у меня есть ManagerThread, который запускает WorkerThreads для вычисления neibhbors каждой ячейки. Итак, сейчас для каждой ячейки запускается один WorkerThread. Как я могу повторно использовать существующий поток, который завершил свою работу?
Образец пула потоков, похоже, является решением, но я не понимаю, что делать, чтобы предотвратить исчезновение потока после завершения его работы.
ps: Я не ожидаю получить большую производительность для этой конкретной задачи, просто хочу поэкспериментировать, как работает многопоточность, прежде чем применять ее к более сложным частям кода.
Спасибо
Ответы
Ответ 1
Посмотрите на Java SE, предоставив java.util.concurrent
API. Вы можете создать threadpool, используя Executors#newFixedThreadPool()
, и вы можете отправлять задания с помощью ExecutorService
. Не нужно изобретать свой собственный поток. Также см. учебник Sun по этому вопросу.
Ответ 2
при использовании пула потоков (java.util.concurrent), вы никогда не инициализировали поток, а скорее пропускаете Runnables в пул потоков.
вам не нужно беспокоиться о жизненном цикле потока, просто выполняйте любую работу, которую вам нужно выполнить в runnable, и дайте ей выйти, когда это будет сделано.
Ответ 3
Посмотрите на использование CyclicBarrier synchro: http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/CyclicBarrier.html
Ответ 4
Хорошо, если бы мне пришлось кодировать эту логику себе, а не использовать такой пакет, как Quartz из OpenSymphony, я бы сделал следующее:
У меня будет WorkerThread, который расширяет Thread. Этот класс также будет иметь частную собственность под названием runnable, которая является Runnable. Это свойство будет содержать ссылку на код, который вы хотите выполнить. У вас есть публичный сеттер.
Код основного потока начнется с запуска runnable, с которого вы его инициализировали, а затем переключитесь в состояние ожидания. Прежде чем это сделать, он отметит менеджеру пула, который он завершил, и он может быть возвращен в пул. В следующий раз, когда вам нужен поток, вы выбираете один из пула, вызываете setRunnable, который устанавливает свойство runnable, а затем просыпает поток. Он вернется к работе, войдет в бесконечный цикл: выполнит и выполнит и вернется в состояние ожидания.