Как запустить/остановить/перезапустить поток в Java?

Вызов Java кодирует от Matlab

49
задан Stefan van den Akker 27 April 2015 в 00:51
поделиться

7 ответов

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

Вариант 1: Создайте новый поток, а не пытайтесь перезапустить его.

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

Редактировать на основе комментария:

Чтобы «убить» поток, вы можете сделать что-то вроде следующего.

yourThread.setIsTerminating(true); // tell the thread to stop
yourThread.join(); // wait for the thread to stop
42
ответ дан 7 November 2019 в 11:50
поделиться

Обзор java.lang.Thread .

Для запуска или перезапуска (после остановки потока вы не можете перезапустить тот же поток, но это не так ' t имеет значение; просто создайте новый экземпляр Thread ):

// Create your Runnable instance
Task task = new Task(...);

// Start a thread and run your Runnable
Thread t = new Thread(task);

Чтобы остановить его, используйте метод в экземпляре Task , который устанавливает флаг, сообщающий о выполнении ] метод выхода; при возврате из run выходит из потока. Если вашему вызывающему коду необходимо знать, что поток действительно остановлен, прежде чем он вернется, вы можете использовать join :

// Tell Task to stop
task.setStopFlag(true);

// Wait for it to do so
t.join();

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

9
ответ дан 7 November 2019 в 11:50
поделиться

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

Эти две статьи Swing Worker и Concurrency могут помочь вам определить лучшее решение вашей проблемы.

5
ответ дан 7 November 2019 в 11:50
поделиться

Как заявил Тейлор Л., вы не можете просто «остановить» поток (вызвав простой метод) из-за того, что он может оставить вашу систему в нестабильном состоянии, поскольку внешний вызывающий поток может не знать, что происходит внутри вашего потока.

С учетом вышесказанного, лучший способ «остановить» поток - это заставить поток следить за собой, чтобы он знал и понимал, когда он должен остановиться .

3
ответ дан 7 November 2019 в 11:50
поделиться

Если ваша задача выполняет какое-либо действие в цикле, есть способ приостановить / перезапустить обработку, но я думаю, что это должно быть вне того, что в настоящее время предлагает Thread API. Если это однократный процесс, я не знаю ни о каком способе приостановить / перезапустить, не используя API, который устарел или больше не разрешен.

Что касается циклических процессов, самый простой способ, который я мог придумать, - это код который порождает Task, создает экземпляр ReentrantLock и передает его задаче, а также сохраняет саму ссылку. Каждый раз, когда задача входит в свой цикл, она пытается заблокировать экземпляр ReentrantLock, а когда цикл завершается, он должен разблокироваться. Возможно, вы захотите инкапсулировать все эти try / finally, убедившись, что вы сняли блокировку в конце цикла, даже если возникнет исключение.

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

Чтобы навсегда остановить поток, я бы использовал обычный API или оставил флаг в Задаче и установщик для флага (что-то вроде стоп немедленно). Когда цикл обнаруживает истинное значение этого флага, он останавливает обработку и завершает выполнение метода.

Чтобы перезапустить поток, просто разблокируйте его из основного кода, это позволит задаче возобновить свои циклы.

Чтобы навсегда остановить поток, я бы использовал обычный API или оставил флаг в Задаче и установщик для флага (что-то вроде стоп немедленно). Когда цикл обнаруживает истинное значение этого флага, он останавливает обработку и завершает выполнение метода.

Чтобы перезапустить поток, просто разблокируйте его из основного кода, это позволит задаче возобновить свои циклы.

Чтобы навсегда остановить поток, я бы использовал обычный API или оставил флаг в Задаче и установщик для флага (что-то вроде стоп немедленно). Когда цикл обнаруживает истинное значение этого флага, он останавливает обработку и завершает выполнение метода.

0
ответ дан 7 November 2019 в 11:50
поделиться

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

Существуют методы для уничтожения потоков из другого потока (например, вашего создателя), но в целом они небезопасны. Может быть безопаснее, если ваш поток постоянно проверяет какой-либо флаг, чтобы увидеть, следует ли ему продолжать (я предполагаю, что в вашем потоке есть какой-то цикл), и попросите внешний «контроллер» изменить состояние этого флага.

Вы можете увидеть немного больше: http://java.sun.com/j2se/1.4.2/docs/guide/misc/threadPrimitiveDeprecation.html

Могу я спросить, почему вы хотите убить поток и перезапустить его? Почему бы ему просто не подождать, пока его услуги снова не потребуются? В Java есть механизмы синхронизации именно для этой цели. Поток будет спать до тех пор, пока контроллер не уведомит его о продолжении выполнения.

0
ответ дан 7 November 2019 в 11:50
поделиться

Невозможно завершить поток, если код, выполняющийся в этом потоке, не проверит и не разрешит завершение.

Вы сказали: «К сожалению, я должен убить / перезапустить его ... Я не делаю» У меня есть полный контроль над содержимым потока, и в моей ситуации это требует перезапуска "

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

В вашем сообщении вы сказали: «Моя первая попытка была с ExecutorService, но я не могу найти способ перезапустить задачу. Когда я использую .shutdownnow () ...»

Если вы посмотрите на источник «shutdownnow» он просто проходит и прерывает текущие потоки. Это не остановит их выполнение, если код в этих потоках не проверит, не был ли он прерван, и, если да, останавливает само исполнение. Так что shutdownnow, вероятно, не делает то, что вы думаете.

Позвольте мне проиллюстрировать, что я имею в виду, когда говорю, что содержимое потока должно допускать завершение этого потока:

myExecutor.execute(new Runnable() {
 public void run() {
  while (true) {
    System.out.println("running");
  }
 }
 });
myExecutor.shutdownnow();

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

myExecutor.execute(new Runnable() {
 public void run() {
  while (!Thread.interrupted()) {
    System.out.println("running");
  }
 }
 });
myExecutor.shutdownnow();

Поскольку этот поток проверяет, был ли он прерван / завершен / завершен.

Итак, если вам нужен поток, который вы можете закрыть, вам нужно сделать убедитесь, что он проверяет, не был ли он прерван. Если вам нужен поток, который можно «выключить» и «перезапустить», вы можете сделать исполняемый, который может принимать новые задачи, как было упомянуто ранее.

Почему вы не можете закрыть работающий поток? На самом деле я соврал, можете позвонить " но почему это плохая идея? Когда вы остановите поток, поток может находиться в синхронизированном (или другом критическом разделе, но здесь мы ограничимся разделами, охраняемыми синхронизированным ключевым словом). Предполагается, что блоки синхронизации должны выполняться целиком и только одним потоком, прежде чем к ним будет обращаться какой-либо другой поток. Если вы остановите поток в середине блока синхронизации, защита, установленная блоком синхронизации, станет недействительной, и ваша программа перейдет в неизвестное состояние. Разработчики заставляют помещать вещи в блоки синхронизации, чтобы поддерживать синхронизацию, если вы используете threadInstance.stop (), вы разрушаете смысл синхронизации, то, что разработчик этого кода пытался выполнить, и как разработчик этого кода ожидал, что его синхронизированные блоки будут

но почему это плохая идея? Когда вы остановите поток, поток может находиться в синхронизированном (или другом критическом разделе, но здесь мы ограничимся разделами, охраняемыми синхронизированным ключевым словом). Предполагается, что блоки синхронизации должны выполняться целиком и только одним потоком, прежде чем к ним будет обращаться какой-либо другой поток. Если вы остановите поток в середине блока синхронизации, защита, установленная блоком синхронизации, станет недействительной, и ваша программа перейдет в неизвестное состояние. Разработчики заставляют помещать вещи в блоки синхронизации, чтобы поддерживать синхронизацию, если вы используете threadInstance.stop (), вы разрушаете смысл синхронизации, то, что разработчик этого кода пытался выполнить, и как разработчик этого кода ожидал, что его синхронизированные блоки будут

но мы ограничимся разделами, охраняемыми синхронизированным ключевым словом здесь), когда вы остановите его. Предполагается, что блоки синхронизации должны выполняться целиком и только одним потоком, прежде чем к ним будет обращаться какой-либо другой поток. Если вы остановите поток в середине блока синхронизации, защита, установленная блоком синхронизации, станет недействительной, и ваша программа перейдет в неизвестное состояние. Разработчики заставляют помещать вещи в блоки синхронизации, чтобы поддерживать синхронизацию, если вы используете threadInstance.stop (), вы разрушаете смысл синхронизации, то, что разработчик этого кода пытался выполнить, и как разработчик этого кода ожидал, что его синхронизированные блоки будут

но мы ограничимся разделами, охраняемыми синхронизированным ключевым словом здесь), когда вы остановите его. Предполагается, что блоки синхронизации должны выполняться целиком и только одним потоком, прежде чем к ним будет обращаться какой-либо другой поток. Если вы остановите поток в середине блока синхронизации, защита, установленная блоком синхронизации, станет недействительной, и ваша программа перейдет в неизвестное состояние. Разработчики заставляют помещать вещи в блоки синхронизации, чтобы поддерживать синхронизацию, если вы используете threadInstance.stop (), вы разрушаете смысл синхронизации, то, что разработчик этого кода пытался выполнить, и как разработчик этого кода ожидал, что его синхронизированные блоки будут

Предполагается, что блоки синхронизации должны выполняться целиком и только одним потоком, прежде чем к ним будет обращаться какой-либо другой поток. Если вы остановите поток в середине блока синхронизации, защита, установленная блоком синхронизации, станет недействительной, и ваша программа перейдет в неизвестное состояние. Разработчики заставляют помещать вещи в блоки синхронизации, чтобы поддерживать синхронизацию, если вы используете threadInstance.stop (), вы разрушаете смысл синхронизации, то, что разработчик этого кода пытался выполнить, и как разработчик этого кода ожидал, что его синхронизированные блоки будут

Предполагается, что блоки синхронизации должны выполняться целиком и только одним потоком, прежде чем к ним будет обращаться какой-либо другой поток. Если вы остановите поток в середине блока синхронизации, защита, установленная блоком синхронизации, станет недействительной, и ваша программа перейдет в неизвестное состояние. Разработчики заставляют помещать вещи в блоки синхронизации, чтобы поддерживать синхронизацию, если вы используете threadInstance.stop (), вы разрушаете смысл синхронизации, то, что разработчик этого кода пытался выполнить, и как разработчик этого кода ожидал, что его синхронизированные блоки будут

9
ответ дан 7 November 2019 в 11:50
поделиться
Другие вопросы по тегам:

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