Java start thread already started

How to start/stop/restart a thread in Java?

My problem is, that if a want to start the thread with thread.start(runnable) by clicking the button, I get this: IllegalThreadStateException: Thread already started (I thought the thread was terminated after the break because the the loop is over, but it seems that I am wrong). You should just be able to start a new instance of the thread in its place Solution 3: Take a boolean variable and wrap the contents you need to run continusly in the thread with a while loop that runs forever till Run is set to false then on clicking the button set the variable to false, for example :- Question: I have 2 threads, the «main» thread which starts a secondary thread to run a little process.

Stop and restart a already running thread

The Thread should end if I press a button, which sets the isButtonPressed to true. My problem is, that if a want to start the thread with thread.start(runnable) by clicking the button, I get this: IllegalThreadStateException: Thread already started (I thought the thread was terminated after the break because the the loop is over, but it seems that I am wrong).

Thread thread = new Thread(runnable); thread.start(runnable); 
 Runnable runnable = new Runnable() < @Override public void run() < time = 10; for (int i = 10; i >); try < Thread.sleep(1000); >catch (InterruptedException e) < >if (isButtonPressed) < break; >if (time == 0) < resetVisibleState(); break; >else < time--; >> > >; 

Java threads are not restartable. For what you are trying to achieve, you could create a new thread each time, or you could look at an ExecutorService. Just create a single threaded executor (Executors.newSingleThreadExecutor), and submit your runnable to it every time you need it to run.

ExecutorService executor = Executors.newSingleThreadExecutor(); executor.submit(runnable); 

From my understanding you need to start a new thread. You cannot re-start a thread that has ran its course.

Since you are correctly stopping the old one via your isButtonPressed . You should just be able to start a new instance of the thread in its place

Take a boolean variable and wrap the contents you need to run continusly in the thread with a while loop that runs forever till Run is set to false then on clicking the button set the variable to false, for example :-

volatile boolean run = true; Thread t = new Thread() < while(run) < // whatever is here runs till Run is false >> t.start(); /*now when the button is pressed just trigger Run as false and the thread will be ended later call t.start() when you need to start the thread again.*/ 

Restart a thread after exception is caught, As a rule, if a thread fails, it terminates It does not look good that a failed thread «recreates» itself. The better solution would be to

130 How can a dead thread be restarted?

Welcome to RedSysTech, a practical Java Learning Channel. This is not the typical Java text Duration: 9:43

Can we restart a dead thread in Java?

In this video you will understand Whether Can we restart a dead thread in Java or not?
Duration: 2:15

Читайте также:  Си шарп блок схема

How can I start a thread from another and restart a thread after execution?

I have 2 threads, the «main» thread which starts a secondary thread to run a little process.

The «main» thread must wait for the secondary thread for a few of seconds to complete the process, after that time, the «main» thread must start again no matter what happened with the process of the secondary thread.

If the secondary process ended earlier, the «main» thread must start to work again.

How can I start a thread from another, wait for the end of execution, and restart the thread after?

I have a code here, but the ExampleRun class, must wait, for example, 10 sec and start again, no matter what happend with MyProcess

public class ExampleRun < public static void main(String[] args) < MyProcess t = new MyProcess(); t.start(); synchronized (t) < try < t.wait(); >catch (InterruptedException e) < System.out.println("Error"); >> > 
public class MyProcess extends Thread < public void run() < System.out.println("start"); synchronized (this) < for (int i = 0; i < 5; i++) < try < System.out.println("I sleep"); sleep(1000); >catch (InterruptedException e) < e.printStackTrace(); >> flag = true; System.out.println("Wake up"); notify(); > > > 

The simplest way to achieve what you want is to use Thread.join(timeout) .

Also, do not use synchronized , wait , or notify on Thread objects. This will interfere with the Thread.join implementation. See the documentation for details.

Here’s what your main program would look like:

public static void main(String[] args) < MyProcess t = new MyProcess(); t.start(); try < t.join(10000L); >catch (InterruptedException ie) < System.out.println("interrupted"); >System.out.println("Main thread resumes"); > 

Note that when the main thread resumes after the join() call, it can’t tell whether the child thread completed or whether the call timed out. To test this, call t.isAlive() .

Your child thread of course could do anything, but it’s important for it not to use synchronized , wait , or notify on itself. For example, here’s a rewrite that avoids using these calls:

class MyProcess extends Thread < public void run() < System.out.println("MyProcess starts"); for (int i = 0; i < 5; i++) < try < System.out.println("MyProcess sleeps"); sleep(1000); >catch (InterruptedException e) < e.printStackTrace(); >> System.out.println("MyProcess finishes"); > > 

You can do this with a simple lock method:

public static void main (String[] args) < // create new lock object Object lock = new Object(); // create and start thread Thread t = new Thread(() -> < // try to sleep 1 sec try < Thread.sleep(1000); >catch (InterruptedException e) < /* do something */ >// notify main thread synchronized (lock) < lock.notifyAll(); >>; t.start(); // wait for second thread to finish synchronized (lock) < while (t.isAlive()) lock.wait(); >// second thread finished System.out.println("second thread finished :)"); > 

You could call Thread.join() on the Thread you want to wait for, per the Javadoc,

Waits for this thread to die.

Alternatively, you could use a Future and simply call get() , from its’ Javadoc,

Waits if necessary for the computation to complete, and then retrieves its result.

Execute two threads in parallel and restart the first one when it ends, You can just store a boolean variable, let’s call it isComplete , that stores whether the long task has completed or not.

Synchronized block still locked after thread restart

I try to restart thread but synchronized block in thread keep locked after restarted. I shouldn’t change socket properties because some processes take too long but when network connection lost it hangs forever. I try to use InterruptedException but it doesn’t work. Is there any way to release this lock?

public static void main(String[] args) < try < synchronizedBlock t1 = new synchronizedBlock(); t1.start(); Thread.sleep(500); t1.cancel(); t1 = new synchronizedBlock(); t1.start(); >catch (Exception e) < e.printStackTrace(); >while (true) < >> public class synchronizedBlock extends Thread < boolean isRunning = true; boolean isRunning2 = true; public static Object[] locks = new Object[5]; public synchronizedBlock() < for (Integer i = 0; i < 5; i++) < synchronizedBlock.locks[i] = i; >> public void cancel() < isRunning = false; interrupt(); >public void socketProces() < while (isRunning2) < >> public void proces(int index) < try < synchronized (locks[index]) < System.out.println("Synchronized Block Begin"); socketProces(); >> catch (Exception e) < e.printStackTrace(); >> @Override public void run() < try < System.out.println("Run begin"); while (isRunning) < proces(1); >Thread.sleep(1); > catch (InterruptedException e) < //Do Something >catch (Exception e) < e.printStackTrace(); >> > 
Run begin Synchronized Block Begin Run begin 

When you start the synchronizedBlock thread you’ll get a stack trace like this I think: run -> proces -> socketProcess . Then because isRunning2 = true , the thread will enter an infinite loop in socketProcess and never terminate.

Читайте также:  Среднее арифметическое java stream

Keep in mind that in Java there is no such thing as ‘restarting’ a thread . Once started, a thread can never be restarted. Indeed, you are creating two sycnchronizedBlock objects, not restarting a single object.

As a side note, it is generally problematic to overwrite static state in a class constructor, as you’re doing with the locks variable, without synchronization.

The issue here is the Integer cache which is used in the for loop to initialize the synchronizedBlock.locks array:

When this code is run again, due to the constructor of the second synchronizedBlock , the synchronizedBlock.locks array contains the same Integer instances which where created when this for loop was executed for the first time. This means that the synchronized (locks[index]) lock will be on the same Integer object. As you have already one thread holding the lock for the Integer(1) object, the second thread waits outside the lock waiting for it to be released.

This is also problematic in combination with the fact that the first thread is not terminating. Your method

is an endless loop as you don’t change the value of isRunning2 , ever. Also, the interrupt() method itself does not stop any thread. Instead, it sets just an internal flag in the Thread class, which can be checked with isInterrupted() and interrupted() . You have to check this flag and react on it like «Oh, someone wants me to stop, so I stop now».

To solve your problem you should at least quit your thread when the «isInterrupted» flag of the Thread instance is set. You can do it like this:

Instead of returning from socketProces() normally you could throw an InterruptedException like other methods do.

Also, depending on how you want to initialize/use the instances you want to lock on with synchronized(. ) , you might want to consider on how you create/fill the synchronizedBlock.locks array and which objects you want to use (the Integer cache might be problematic here). It depends on you if the creation of a new synchronizedBlock instance will/should/shouldn’t create new objects to lock on in the synchronizedBlock.locks array.

Why does this small Java program make MacOS restart?, Cause of the restart is a counter measure by OS, when OS becomes CPU heavy and threads consumes the OS resources

Источник

Читайте также:  Скрипты для html чата

Законно ли вызывать метод start дважды в одном потоке?

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

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

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

10 ответов

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

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

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

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

Благодарю. Я проверил документацию с помощью IDE и учебника по Java для потоков (и Google тоже). Я проверю спецификации API в будущем. Это критическое «никогда не разрешено начинать более одного раза . » не в других чтениях.

@coobird, если я назначу имя объекта старого потока новому потоку (), после завершения старого потока будет ли старый поток собираться мусором (то есть автоматически ли он перерабатывается или это нужно делать явно)?

Этот ответ немного устарел. Если современная Java-программа должна выполнить задачу более одного раза, она не должна каждый раз создавать новый Thread . Вместо этого он должен отправить задачу в пул потоков (например, java.util.concurrent.ThreadPoolExecutor )

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

С точки зрения того, что вы можете сделать для повторных вычислений, кажется, что вы можете использовать метод 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 на ваш расчет, это может быть именно то, что вам нужно.

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 на соответствующую запись на Handler .

Источник

Оцените статью