This question already has answers here:
Is it legal to call the start method twice on the same Thread?
(11 answers)
Closed 9 years ago.
I am making a program and I need one thread to stop and another to start. my problem is that if I do t1.stop() than t1.start() I get the java.lang.IllegalThreadStateException
if (t1.isAlive() == true){
t1.stop();
// above I stop the thread and call another
t2.start();
System.out.println("t1 was playing");
}else{
t2.stop();
t1.start();
// above I stop the other thread and want to start the first thread again, but when I run the program I get the exception i said above
}
When a thread is stopped, you cannot restart it.
However, you can create and start a new thread.
Also, you can suspend and resume the thread.
The java primitive to suspend and resume a thread (along with stop etc) is deprecated. See this to figure how you can achieve best what you need - http://docs.oracle.com/javase/7/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html
Check how you can do the equivalent of suspend & resume
What should I use instead of Thread.suspend and Thread.resume?
As with Thread.stop, the prudent approach is to have the "target thread" poll a variable indicating the desired state of the thread (active or suspended). When the desired state is suspended, the thread waits using Object.wait. When the thread is resumed, the target thread is notified using Object.notify.
Example code is given in the same answer to help you achieve this.
Thread#stop is deprecated and you shouldn't use it.
From the JavaDocs
stop()
Deprecated.
This method is inherently unsafe. Stopping a
thread with Thread.stop causes it to unlock all of the monitors that
it has locked (as a natural consequence of the unchecked ThreadDeath
exception propagating up the stack). If any of the objects previously
protected by these monitors were in an inconsistent state, the damaged
objects become visible to other threads, potentially resulting in
arbitrary behavior. Many uses of stop should be replaced by code that
simply modifies some variable to indicate that the target thread
should stop running. The target thread should check this variable
regularly, and return from its run method in an orderly fashion if the
variable indicates that it is to stop running. If the target thread
waits for long periods (on a condition variable, for example), the
interrupt method should be used to interrupt the wait. For more
information, see Why are Thread.stop, Thread.suspend and Thread.resume
Deprecated?.
Threads are also non-re-entrant, or, are single use. Once the run method terminates, they can not be restarted
Related
This question already has answers here:
How do you kill a Thread in Java?
(17 answers)
Closed 2 years ago.
I want to create a thread to judge user codeļ¼
FutureTask<Integer> futureTask = new FutureTask(() -> run(type)); // run is a method
Thread thread = new Thread(futureTask);
thread.start();
As we all known, an infinite loop may be written in the user code, so the method run will be working all the time and the Thread thread will not stop. I want to terminate this thread after timeout duration. How can I terminate it instead of using Thread.stop because it's unsafe?
The correct way to deal with a thread that needs to be stopped is to design the thread's code so that it responds appropriately to being interrupted:
Long computations need to occasionally check the current thread's "interrupted" flag.
InterruptedException should be handled appropriately.
The thread application code's response to the interrupt should be to gracefully stop what it is doing1 and (typically) allow the thread to terminate.
(You could also use a custom flag implemented using a volatile shared variable instead of the interrupted flag. However, that doesn't deal with interrupting wait, sleep and similar operations, and is therefore a poor substitute for interrupts.)
The unsafe way is to call the deprecated Thread.stop() method. (The javadocs explain why it is unsafe, and we don't need to repeat that here.)
The (related) Thread.stop(Throwable) method was removed in Java 11; see:
Java 11 Removes stop() and destroy() Methods.
https://bugs.openjdk.java.net/browse/JDK-8204243
Unfortunately, there is nothing in between these two approaches for interrupting a thread.
If you cannot get your long running thread to cooperate, the safe alternative would be to run it in a separate process; e.g. using System.ProcessBuilder etcetera to run the java command. The (external) process could then be killed if it took too long. The downsides include:
An external process cannot access the current JVM's variables, etcetera. So you need to use a different mechanism to pass information between the parent and child processes.
Starting a new JVM is a lot more expensive than starting a new thread.
1 - For example, if the thread owns resources such as open files or sockets, it should release them. If it is performing an action for some other thread that will be waiting for the result, it should signal (in the appropriate way) that there will be no result. And so on.
Terminating thread from outside is ALWAYS unsafe and very strongly discouraged. You need to notify the thread that you want it to terminate and the thread must do it itself. That is done with method interrupt() of the class Thread. In your example it would be from the main code to call thread.interrupt() That will cause the interrupt flag to be raised in your thread. In your run method of your thread you should check for that flag (See methods interrupted() and isInterrupted() in the class Thread). Once you see that your flag is raised, break out of the loop and finish the method. That will stop your thread.
This question already has answers here:
When is a Java thread alive?
(7 answers)
Closed 2 years ago.
Is the interruption bit of a java.lang.Thread guaranteed to be set, when a thread is interrupted after it was started (Thread#start() was called) but before it begins its execution (its run method is not yet called by the JVM)?
So that within the thread Thread.interrupted() returns true or a InterruptedException is thrown when a method is called, that reacts to interruption in this way,
Or with an example:
Will the following snippet of Java code always, under any circumstances, print true?
AtomicBoolean flag = new AtomicBoolean(false);
Thread thread = new Thread(() -> {
while (!flag.get()) {}
System.out.println(Thread.interrupted());
});
thread.start();
thread.interrupt();
flag.set(true);
The java-doc of java.lang.Thread#interrupt() says:
Interrupting a thread that is not alive need not have any effect.
And the doc of java.lang.Thread#interrupted() says:
A thread interruption ignored because a thread was not alive at the
time of the interrupt will be reflected by this method returning false.
My assumption is that alive from these docs refers to the description in Thread#isAlive():
A thread is alive if it has been started and has not yet died.
From this, my answer would be yes. But I read in some sources that thread interruptions, which are done before the thread is running, are ignored. When I ran the code snippet it always printed true (but we know this isn't a guarantee in concurrent programming).
Therefore I'm searching for clarification.
It depends on scheduler when it is actually starting your thread and when finishing and you dont have control over thread scheduler. It is not gauranteed that thread is immediately started when you call thread.start(). It is possible that main thread has got chance to excute thread.interrupt(); before your thread got CPU chance.
Or with an example: Will the following snippet of Java code always, under any circumstances, print true?
If you have written this in main method then it will always print true because main is deamon thread in java and runs until its child thread gets completed. If main thread exited before thread was scheduled then nothing will be printed
This question already has answers here:
Why do InterruptedExceptions clear a thread's interrupted status?
(4 answers)
Closed 2 years ago.
In many sources I found that Thread.interrupted() method clears interrupt status of thread, but in none of them there was explanation of the reason why this method works exactly in this way.
I still feel confused a little because of lack of understanding of this reason and lack of understating of what problem designers of java tried to solve by clearing interrupt status.
I will appreciate very much if someone could explain that and show some example.
The idea behind thread interruption is that one thread may signal another to request that it interrupt is regular processing to divert its attention to some thread-specific special action. What a thread actually does in response depends entirely on the code running in that thread.
There are two main ways in which a Thread can determine whether it has been interrupted:
Several Thread and Object methods will throw an InterruptedException if invoked in a thread whose interrupted status is set, or if a thread is interrupted while the method is executing. The interrupted status is cleared in this event, presumably because the exception is considered adequate notice of the interruption.
Code running in the thread can invoke Thread.interrupted() or Thread.currentThread().isInterrupted() to proactively test for an interrupt. The former also resets the interrupted status; the latter does not, likely because it is an instance method -- interrupts must not be lost in the event that one thread calls the isInterrupted() method of a different one.
The techniques that cause the interrupt status to be reset do so in order that the thread is able to handle subsequent interruptions. The key point here is perhaps that thread interruption is not intended to necessarily cause the interrupted thread to shut down (although that is indeed one response that a thread can make). It is a more general mechanism.
From jdoc
An interrupt is an indication to a thread that it should stop what it is doing and do something else. It's up to the programmer to decide exactly how a thread responds to an interrupt, but it is very common for the thread to terminate
and
By convention, any method that exits by throwing an InterruptedException clears interrupt status when it does so. However, it's always possible that interrupt status will immediately be set again, by another thread invoking interrupt.
So Thread.interrupted clears the flag because it's always possible that interrupt status will immediately be set again, by another thread invoking interrupt.
Explanation https://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html
While going through the javadoc for the notifyAll() method under Object class came through the following lines:
If the current thread is interrupted by any thread before or while it is waiting, then an
InterruptedException is thrown. This exception is not thrown until the lock status of this object has been restored as described above.
The point is:
the current thread is interrupted while it is waiting
What does this means? Can a thread be interrupted while it is waiting?
If yes, why? What is the use of it?
The meaning of "thread getting interrupted" in Java means that the thread's interrupted flag has been set, nothing more. However, most methods of the JDK which make the thread wait will immediately find out about this and exit the wait state, throwing an InterruptedException. Such is the case with the methods you have been reading about.
A thread can be interrupted while waiting if another thread calls:
waitingThread.interrupt();
This can happen if you do it yourself of course but also if you use a framework to manage your threads, typically an executor service, and call some of the methods that interrupt the underlying threads (e.g. shutdownNow or if you call future.cancel(true); on the Future returned by the submit method).
The interruption mechanism is how Java enables one thread to tell another one to stop what it is doing and is therefore extremely useful.
I am trying to stop a thread. while stopping my thread i got thread interrupted exception.
What I can do if thread throw interrupted exception. should i catch it and do nothing or do i need to do anything?
You should not 'just stop' a thread. The thing I mostly do is create a public (perhaps static) variable in the Thread's class that indicates when the thread should stop. So something like a declaration of
public volatile bool shouldStop = false;
Then, at the end of every cycle of your thread, you could check if you need to quit (break from the while-loop or something).
Threads can be very annoying to handle! Calling interrupt/stop functions on just a thread itself is possible, but mostly unwanted.
There is a reason .stop() and .suspend() were deprecated and should not be used. This article is relevant:
http://download.oracle.com/javase/1.4.2/docs/guide/misc/threadPrimitiveDeprecation.html
Also I quote the Javadocs:
Deprecated. This method is inherently
unsafe. Stopping a thread with
Thread.stop causes it to unlock all of
the monitors that it has locked (as a
natural consequence of the unchecked
ThreadDeath exception propagating up
the stack). If any of the objects
previously protected by these monitors
were in an inconsistent state, the
damaged objects become visible to
other threads, potentially resulting
in arbitrary behavior. Many uses of
stop should be replaced by code that
simply modifies some variable to
indicate that the target thread should
stop running. The target thread should
check this variable regularly, and
return from its run method in an
orderly fashion if the variable
indicates that it is to stop running.
If the target thread waits for long
periods (on a condition variable, for
example), the interrupt method should
be used to interrupt the wait. For
more information, see Why are
Thread.stop, Thread.suspend and
Thread.resume Deprecated?.
You should find some way (whether by some shared variable or otherwise) to synchronise your threads so the thread can end itself.
It depends on your needs. You can (for example) do something like this:
public void run() {
try {
// do thread stuff
} catch(ThreadInterruptedException ex) {
// close gracefully what needed to be closed
}
}
But the stop method is deprecated. So a better solution is to put some boolean variable to indicate whether the thread should stop or not and provide a method to change it in order to stop the thread (see this question for example).