Intereting Posts
Как использовать элементы управления Xamarin.Form и собственные элементы управления На той же странице Как связать Google +, подписанный с пользователями в Parse backend на Android? Как используются значения android.graphics.Matrix? Центрирование фонового изображения на Android Обнаруживать Moto 360 / circlular shape и onApplyWindowInsetListener не вызывать Переключить навигационный ящик с помощью заголовка панели действий Как получить токен доступа пользователя facebook в android? Повернуть растровое изображение на Android Canvas В чем разница между URI и классом Uri Изображение выходит из камеры на Thunderbolt & G2? Отправка запроса на запросLocationUpdates intentService прерывает обновление местоположения Android: как изменить стиль редактирования текста? Кинжал для Android: ввод объекта в график объекта после вызова setContentView Eclipse: укажите несколько каталогов res, например, указать несколько каталогов src Ионная ошибка отображения, если gps выключен

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

Следующий код приводит к «java.lang.IllegalThreadStateException: Thread уже запущен». Второй раз он запускается в программе.

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

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

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

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

Solutions Collecting From Web of "Является ли законным вызывать метод запуска дважды в одной теме?"

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

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

Более того:

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

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

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

Если 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 .

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

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

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

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

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

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

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

Возьмем пример. Еще раз подумаем о начале потока и вызове метода 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 в методе run (), метод завершен. Исключение в потоке «main» java.lang.IllegalThreadStateException в java.lang.Thread.start (Неизвестный источник) * /

Проверь это

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

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

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

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

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

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

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

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

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

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