Действительно ли законно назвать метод запуска дважды на том же Потоке?

Я не эксперт по этому, но я могу попытаться внести несколько ответов:

  1. NetHack и это являются братьями, открытый исходный код и полагается в большой степени на процедурное поколение уровней (карты). Ссылка к загрузкам его. Если бы Вы больше интересуетесь альбомной/структурой/облаком поколением, я рекомендовал бы искать Gamasutra и GameDev, которые имеют довольно много статей о тех предметах.

  2. AFAIK, я не думаю, существует много различия между языками. Большая часть кода, который Вы видите, будет в C/CPP, потому что это - все еще очень официальный язык Разработчиков игр, но можно использовать что-либо, что Вы хотите...

  3. Хорошо это зависит, если у Вас есть проект, который может извлечь выгоду из такой технологии. Я видел процедурное поколение, используемое в средствах моделирования для армии (который можно считать игрой, хотя они не очень играемы:)).

И маленькое примечание - мое определение, если процедурное поколение - что-нибудь генерирующее много данных из небольшого количества правил или шаблонов и большую случайность, Ваши результаты, может варьироваться:)

88
задан Ravindra babu 30 August 2017 в 07:00
поделиться

5 ответов

Из Спецификации Java API для метода Thread.start :

Запуск потока никогда не разрешен. больше чем единожды. В частности, поток не может быть перезапущен после того, как он завершил выполнение.

Кроме того:

Выдает:
IllegalThreadStateException - если поток уже был запущен.

Так что да, Thread может быть запущен только один раз.

Если да, то что мне делать, если я хочу запустить поток снова?

Если поток необходимо запускать более одного раза, то нужно создать новый экземпляр потока и вызвать start на нем.

109
ответ дан 24 November 2019 в 07:36
поделиться

Совершенно верно. Из документации :

Запуск потока никогда не разрешен. больше чем единожды. В частности, поток не может быть перезапущен после того, как он завершил выполнение.

С точки зрения того, что вы можете сделать для повторных вычислений, кажется, что вы могли бы использовать метод SwingUtilities invokeLater . Вы уже экспериментируете с прямым вызовом run () , что означает, что вы уже думаете об использовании Runnable , а не необработанного Thread . Попробуйте использовать метод invokeLater только для задачи Runnable и посмотрите, подходит ли это немного лучше вашему мышлению.

Вот пример из документации:

 Runnable doHelloWorld = new Runnable() {
     public void run() {
         // Put your UI update computations in here.
         // BTW - remember to restrict Swing calls to the AWT Event thread.
         System.out.println("Hello World on " + Thread.currentThread());
     }
 };

 SwingUtilities.invokeLater(doHelloWorld);
 System.out.println("This might well be displayed before the other message.");

Если вы замените этот вызов println своим вычислением, это может быть именно то, что вам нужно.

РЕДАКТИРОВАТЬ: следя за комментарием, я не заметил тега Android в исходном сообщении. Эквивалент invokeLater в работе Android - это Handler. сообщение (Runnable) . Из его javadoc:

/**
 * Causes the Runnable r to be added to the message queue.
 * The runnable will be run on the thread to which this handler is
 * attached.
 *
 * @param r The Runnable that will be executed.
 *
 * @return Returns true if the Runnable was successfully placed in to the
 *         message queue.  Returns false on failure, usually because the
 *         looper processing the message queue is exiting.
 */

Итак, в мире Android вы можете использовать тот же пример, что и выше, заменив Swingutilities.invokeLater соответствующим сообщением в Handler .

]
13
ответ дан 24 November 2019 в 07:36
поделиться

Только что полученный ответ объясняет, почему вам не следует делать то, что вы делаете. Вот несколько вариантов решения вашей реальной проблемы.

Этот конкретный поток делает некоторые расчет в фоновом режиме, если я не делайте этого в потоке, чем это сделано в потоке пользовательского интерфейса, и пользователь неоправданно долгое ожидание.

Выгрузите собственный поток и используйте AsyncTask .

Или создайте новый поток, когда он вам нужен.

Или настройте свой поток для работы вне очереди работ. (например, LinkedBlockingQueue ) вместо перезапуска потока.

3
ответ дан 24 November 2019 в 07:36
поделиться

Как вы сказали, поток не может быть запущен более одного раза.

Прямо из уст: Спецификация Java API

Никогда не разрешается запускать нить больше чем единожды. В частности, поток не может быть перезапущен после того, как он завершил выполнение.

Если вам нужно повторно запустить все, что происходит в вашем потоке, вам придется создать новый поток и запустить его.

1
ответ дан 24 November 2019 в 07:36
поделиться

Что вам нужно сделать, так это создать Runnable и обернуть его новым Thread каждый раз, когда вы хотите запустить Runnable. Это было бы действительно некрасиво, но вы можете обернуть поток другим потоком, чтобы снова запустить его код, но сделайте это только в том случае, если вам действительно нужно.

2
ответ дан 24 November 2019 в 07:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: