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

Следующий код приводит к java.lang.IllegalThreadStateException: Thread already started когда я дважды вызывал метод start() в программе.

 updateUI.join(); if (!updateUI.isAlive()) updateUI.start(); 

Это происходит во второй раз, когда updateUI.start() . Я прошел через него несколько раз, и stream вызывается и завершается до завершения, прежде чем нажать updateUI.start() .

Вызов updateUI.run() позволяет избежать ошибки, но заставляет stream запускаться в streamе пользовательского интерфейса (вызывающий stream, как указано в других сообщениях на SO), чего я не хочу.

Можно ли запустить Thread только один раз? Если да, то чем я занимаюсь, если я хочу снова запустить stream? Этот конкретный stream выполняет некоторые вычисления в фоновом режиме, если я не делаю этого в streamе, чем это делается в streamе пользовательского интерфейса, и пользователь имеет необоснованно долгое ожидание.

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

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

Более того:

Броски:
IllegalThreadStateException – если stream уже запущен.

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

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

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

Абсолютно верно. Из документации :

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

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

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

  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 своими вычислениями, это может быть именно то, что вам нужно.

EDIT: после комментария, я не заметил тег Android в исходном сообщении. Эквивалентом invokeLater в работе Android является Handler.post(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 соответствующей Swingutilities.invokeLater на Handler .

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

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

AsyncTask свой stream и используйте AsyncTask .

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

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

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

Нет , мы не можем запустить Thread снова, так что это приведет к запуску runtimeException java.lang.IllegalThreadStateException. >

Причина в том, что метод run () выполняется Thread, он переходит в мертвое состояние.

Давайте возьмем пример. Еще раз подумаем о начале streamа и вызове метода start () на нем (который внутренне собирается вызвать метод run ()) для нас – это то, что, как просить мертвого человека просыпаться и бегать. Поскольку, после завершения своей жизни, человек переходит в мертвое состояние.

 public class MyClass implements Runnable{ @Override public void run() { System.out.println("in run() method, method completed."); } public static void main(String[] args) { MyClass obj=new MyClass(); Thread thread1=new Thread(obj,"Thread-1"); thread1.start(); thread1.start(); //will throw java.lang.IllegalThreadStateException at runtime } } 

/ * OUTPUT in run (), метод завершен. Исключение в streamе «main» java.lang.IllegalThreadStateException в java.lang.Thread.start (Неизвестный источник) * /

Проверь это

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

Прямо из уст лошади: Java API Spec

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

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

Повторное использование streamа является незаконным действием в Java API. Однако вы можете перенести его в runnable-реализацию и снова запустить этот экземпляр.

Да, мы не можем запустить уже запущенный stream. Он будет вызывать IllegalThreadStateException во время выполнения – если stream уже запущен.

Что делать, если вам действительно нужно запустить stream: Вариант 1) Если stream нужно запускать более одного раза, тогда нужно создать новый экземпляр Thread и запустить его.

Можно ли запустить Thread только один раз?

Да. Вы можете запустить его ровно один раз.

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

Не запускайте Thread снова. Вместо этого создайте Runnable и опубликуйте его в обработчике HandlerThread . Вы можете отправить несколько объектов Runnable . Если вы хотите отправить данные обратно в stream пользовательского интерфейса, run() метод Runnable run() , разместите Message о Handler пользовательского интерфейса и обработайте handleMessage

Обратитесь к этому сообщению, например, к коду:

Android: Тост в streamе

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

Я должен был исправить утечку ресурсов, вызванную программистом, который создал Thread, но вместо того, чтобы начать () его, он вызвал метод run () – напрямую. Поэтому избегайте этого, если вы действительно не знаете, какие побочные эффекты он вызывает.

  • Что такое sharedUserId в Android и как оно используется?
  • Вызов super ()
  • Android: прослушиватель изменений в подключении к Интернету
  • Selenium - базовая аутентификация через URL-адрес
  • Включить частичную компиляцию в IntelliJ IDEA
  • Как отобразить два столбца ListView в Android?
  • Как основной stream, созданный Java
  • Разбор строк запроса на Android
  • как динамически обновлять xml-файл из другого XML-файла?
  • Как поддерживать несколько версий Android в коде?
  • OnClickListener не отвечает
  • Давайте будем гением компьютера.