I wrote a thread, it is taking too much time to execute and it seems it is not completely done. I want to stop the thread gracefully. Any help ?
The good way to do it is to have the run() of the Thread guarded by a boolean variable and set it to true from the outside when you want to stop it, something like:
class MyThread extends Thread
{
volatile boolean finished = false;
public void stopMe()
{
finished = true;
}
public void run()
{
while (!finished)
{
//do dirty work
}
}
}
Once upon a time a stop() method existed but as the documentation states
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.
That's why you should have a guard..
The bad part about using a flag to stop your thread is that if the thread is waiting or sleeping then you have to wait for it to finish waiting/sleeping. If you call the interrupt method on the thread then that will cause the wait or sleep call to be exited with an InterruptedException.
(A second bad part about the flag approach is that most nontrivial code is going to be utilizing libraries like java.util.concurrent, where the classes are specifically designed to use interruption to cancel. Trying to use the hand rolled flag in a task passed into an Executor is going to be awkward.)
Calling interrupt() also sets an interrupted property that you can use as a flag to check whether to quit (in the event that the thread is not waiting or sleeping).
You can write the thread's run method so that the InterruptedException is caught outside whatever looping logic the thread is doing, or you can catch the exception within the loop and close to the call throwing the exception, setting the interrupt flag inside the catch block for the InterruptedException so that the thread doesn't lose track of the fact that it was interrupted. The interrupted thread can still keep control and finish processing on its own terms.
Say I want to write a worker thread that does work in increments, where there's a sleep in the middle for some reason, and I don't want quitting the sleep to make processing quit without doing the remaining work for that increment, I only want it to quit if it is in-between increments:
class MyThread extends Thread
{
public void run()
{
while (!Thread.currentThread().isInterrupted())
{
doFirstPartOfIncrement();
try {
Thread.sleep(10000L);
} catch (InterruptedException e) {
// restore interrupt flag
Thread.currentThread().interrupt();
}
doSecondPartOfIncrement();
}
}
}
Here is an answer to a similar question, including example code.
You should not kill Thread from other one. It's considered as fairly bad habit. However, there are many ways. You can use return statement from thread's run method.
Or you can check if thread has already been interrupted and then it will cancel it's work. F.e. :
while (!isInterrupted()) {
// doStuff
}
Make a volatile boolean stop somewhere. Then in the code that runs in the thread, regularly do
if (stop) // end gracefully by breaking out of loop or whatever
To stop the thread, set stop to true.
I think you must do it manually this way. After all, only the code running in the thread has any idea what is and isn't graceful.
You need to send a stop-message to the Thread and the Thread itself needs to take action if the message has been received. This is pretty easy, if the long-running action is inside loop:
public class StoppableThread extends Thread {
private volatile boolean stop = false;
public void stopGracefully() {
stop = true;
}
public void run() {
boolean finished = false;
while (!stop && !finished) {
// long running action - finished will be true once work is done
}
}
}
For a thread to stop itself, no one seems to have mentioned (mis)using exception:
abstract class SelfStoppingThread extends Thread {
#Override
public final void run() {
try {
doRun();
} catch (final Stop stop) {
//optional logging
}
}
abstract void doRun();
protected final void stopSelf() {
throw new Stop();
}
private static final class Stop extends RuntimeException {};
}
A subclass just need to override doRun() normally as you would with a Thread, and call stopSelf() whenever it feels like it wants to stop. IMO it feels cleaner than using a flag in a while loop.
Related
I am using Threads (still..) for many stuff right now. I found many methods of thread that I would most likely use marked as deprecated.
Is there any chance to pause/resume thread with some triggers? Most people say to use wait.. but if I don't know the time ? I have some events that can happen after 5 minutes or after 2 hours...
Also .. another thing.
If I have a Thread .. it has an run() method. Now the Thread is started , run does what it has to do and then the Thread dies. Like forever ? The stuff from run() method is done so the Thread is ready to be taken out by garbage collector or is it just in some phase of disabled but still existing ?
Now you have a run method like that :
public void run(){
while(running){
//do stuff...
}
}
If I switch the running to false, run method loops and stops because there is nothing more to do . Does this thread also die ? Can I for example say after some time I want to rerun this thread, so I just set the running to true again and call the run method, or do I have to recreate the Thread once again ?
A Thread can only "live" once. When you create a Thread, you specify a Runnable instance as a target (if you don't, the thread targets itself—it implements Runnable and its default run() method does nothing). In either case, when the thread completes the run() method of its target Runnable, the thread dies.
In the example posed in the question, setting running to true after the run() method has returned will do nothing; the Thread can't be restarted after dying.
If you want to pause a thread, and reuse it later, there are a number of mechanisms. The most primitive is wait() and notify(). Rather than waiting for a specified period of time, you wait until a condition changes, like this:
abstract class Pausable implements Runnable {
private final Object lock = new Object();
private boolean pause = false;
abstract void doSomething();
#Override
public void run() {
while (cantering()) doSomething();
}
private boolean cantering() {
synchronized (lock) {
while (pause) {
try { lock.wait(); }
catch (InterruptedException ex) {
Thread.currentThread().interrupt();
return false;
}
}
}
return true;
}
final void whoa() {
synchronized(lock) {
pause = true;
}
}
final void giddyup() {
synchronized(lock) {
pause = false;
lock.notify();
}
}
}
That's a lot of code, and it's fragile. I've been writing Java for 20 years and I'm not sure I got it right. That's why you should use the right tool from java.util.concurrency. For example, if you are waking up the thread to process a message, use a BlockingQueue, and let the consuming thread wait for messages to arrive on the queue. If you have tasks you want to perform asynchronously in response to some event, create an ExecutorService and submit the tasks. Even if you do want to use something like wait()/notify(), the concurrency package's Condition class gives you a lot more control over locking than intrinsic locks offer.
Can I [...] and call the run method?
If you have a Thread t = ...;, and you write a call to t.run(), you probably are making a mistake.
A Thread is not a thread. A thread is a path of execution through your code. A Thread is an object with methods that can be used to create a new thread and manage its life-cycle.
You create the new thread by calling t.start().
Remember this mantra:
The start() method is the method that the library provides for your code to call when you want to start a new thread.
The run() method is the method that your code provides for the library to call in the new thread.
How do you kill a java.lang.Thread in Java?
See this thread by Sun on why they deprecated Thread.stop(). It goes into detail about why this was a bad method and what should be done to safely stop threads in general.
The way they recommend is to use a shared variable as a flag which asks the background thread to stop. This variable can then be set by a different object requesting the thread terminate.
Generally you don't..
You ask it to interrupt whatever it is doing using Thread.interrupt() (javadoc link)
A good explanation of why is in the javadoc here (java technote link)
In Java threads are not killed, but the stopping of a thread is done in a cooperative way. The thread is asked to terminate and the thread can then shutdown gracefully.
Often a volatile boolean field is used which the thread periodically checks and terminates when it is set to the corresponding value.
I would not use a boolean to check whether the thread should terminate. If you use volatile as a field modifier, this will work reliable, but if your code becomes more complex, for instead uses other blocking methods inside the while loop, it might happen, that your code will not terminate at all or at least takes longer as you might want.
Certain blocking library methods support interruption.
Every thread has already a boolean flag interrupted status and you should make use of it. It can be implemented like this:
public void run() {
try {
while (!interrupted()) {
// ...
}
} catch (InterruptedException consumed)
/* Allow thread to exit */
}
}
public void cancel() { interrupt(); }
Source code adapted from Java Concurrency in Practice. Since the cancel() method is public you can let another thread invoke this method as you wanted.
One way is by setting a class variable and using it as a sentinel.
Class Outer {
public static volatile flag = true;
Outer() {
new Test().start();
}
class Test extends Thread {
public void run() {
while (Outer.flag) {
//do stuff here
}
}
}
}
Set an external class variable, i.e. flag = true in the above example. Set it to false to 'kill' the thread.
I want to add several observations, based on the comments that have accumulated.
Thread.stop() will stop a thread if the security manager allows it.
Thread.stop() is dangerous. Having said that, if you are working in a JEE environment and you have no control over the code being called, it may be necessary; see Why is Thread.stop deprecated?
You should never stop stop a container worker thread. If you want to run code that tends to hang, (carefully) start a new daemon thread and monitor it, killing if necessary.
stop() creates a new ThreadDeathError error on the calling thread and then throws that error on the target thread. Therefore, the stack trace is generally worthless.
In JRE 6, stop() checks with the security manager and then calls stop1() that calls stop0(). stop0() is native code.
As of Java 13 Thread.stop() has not been removed (yet), but Thread.stop(Throwable) was removed in Java 11. (mailing list, JDK-8204243)
There is a way how you can do it. But if you had to use it, either you are a bad programmer or you are using a code written by bad programmers. So, you should think about stopping being a bad programmer or stopping using this bad code.
This solution is only for situations when THERE IS NO OTHER WAY.
Thread f = <A thread to be stopped>
Method m = Thread.class.getDeclaredMethod( "stop0" , new Class[]{Object.class} );
m.setAccessible( true );
m.invoke( f , new ThreadDeath() );
I'd vote for Thread.stop().
As for instance you have a long lasting operation (like a network request).
Supposedly you are waiting for a response, but it can take time and the user navigated to other UI.
This waiting thread is now a) useless b) potential problem because when he will get result, it's completely useless and he will trigger callbacks that can lead to number of errors.
All of that and he can do response processing that could be CPU intense. And you, as a developer, cannot even stop it, because you can't throw if (Thread.currentThread().isInterrupted()) lines in all code.
So the inability to forcefully stop a thread it weird.
The question is rather vague. If you meant “how do I write a program so that a thread stops running when I want it to”, then various other responses should be helpful. But if you meant “I have an emergency with a server I cannot restart right now and I just need a particular thread to die, come what may”, then you need an intervention tool to match monitoring tools like jstack.
For this purpose I created jkillthread. See its instructions for usage.
There is of course the case where you are running some kind of not-completely-trusted code. (I personally have this by allowing uploaded scripts to execute in my Java environment. Yes, there are security alarm bell ringing everywhere, but it's part of the application.) In this unfortunate instance you first of all are merely being hopeful by asking script writers to respect some kind of boolean run/don't-run signal. Your only decent fail safe is to call the stop method on the thread if, say, it runs longer than some timeout.
But, this is just "decent", and not absolute, because the code could catch the ThreadDeath error (or whatever exception you explicitly throw), and not rethrow it like a gentlemanly thread is supposed to do. So, the bottom line is AFAIA there is no absolute fail safe.
'Killing a thread' is not the right phrase to use. Here is one way we can implement graceful completion/exit of the thread on will:
Runnable which I used:
class TaskThread implements Runnable {
boolean shouldStop;
public TaskThread(boolean shouldStop) {
this.shouldStop = shouldStop;
}
#Override
public void run() {
System.out.println("Thread has started");
while (!shouldStop) {
// do something
}
System.out.println("Thread has ended");
}
public void stop() {
shouldStop = true;
}
}
The triggering class:
public class ThreadStop {
public static void main(String[] args) {
System.out.println("Start");
// Start the thread
TaskThread task = new TaskThread(false);
Thread t = new Thread(task);
t.start();
// Stop the thread
task.stop();
System.out.println("End");
}
}
There is no way to gracefully kill a thread.
You can try to interrupt the thread, one commons strategy is to use a poison pill to message the thread to stop itself
public class CancelSupport {
public static class CommandExecutor implements Runnable {
private BlockingQueue<String> queue;
public static final String POISON_PILL = “stopnow”;
public CommandExecutor(BlockingQueue<String> queue) {
this.queue=queue;
}
#Override
public void run() {
boolean stop=false;
while(!stop) {
try {
String command=queue.take();
if(POISON_PILL.equals(command)) {
stop=true;
} else {
// do command
System.out.println(command);
}
} catch (InterruptedException e) {
stop=true;
}
}
System.out.println(“Stopping execution”);
}
}
}
BlockingQueue<String> queue=new LinkedBlockingQueue<String>();
Thread t=new Thread(new CommandExecutor(queue));
queue.put(“hello”);
queue.put(“world”);
t.start();
Thread.sleep(1000);
queue.put(“stopnow”);
http://anandsekar.github.io/cancel-support-for-threads/
Generally you don't kill, stop, or interrupt a thread (or check wheter it is interrupted()), but let it terminate naturally.
It is simple. You can use any loop together with (volatile) boolean variable inside run() method to control thread's activity. You can also return from active thread to the main thread to stop it.
This way you gracefully kill a thread :) .
Attempts of abrupt thread termination are well-known bad programming practice and evidence of poor application design. All threads in the multithreaded application explicitly and implicitly share the same process state and forced to cooperate with each other to keep it consistent, otherwise your application will be prone to the bugs which will be really hard to diagnose. So, it is a responsibility of developer to provide an assurance of such consistency via careful and clear application design.
There are two main right solutions for the controlled threads terminations:
Use of the shared volatile flag
Use of the pair of Thread.interrupt() and Thread.interrupted() methods.
Good and detailed explanation of the issues related to the abrupt threads termination as well as examples of wrong and right solutions for the controlled threads termination can be found here:
https://www.securecoding.cert.org/confluence/display/java/THI05-J.+Do+not+use+Thread.stop%28%29+to+terminate+threads
Here are a couple of good reads on the subject:
What Do You Do With InterruptedException?
Shutting down threads cleanly
I didn't get the interrupt to work in Android, so I used this method, works perfectly:
boolean shouldCheckUpdates = true;
private void startupCheckForUpdatesEveryFewSeconds() {
Thread t = new Thread(new CheckUpdates());
t.start();
}
private class CheckUpdates implements Runnable{
public void run() {
while (shouldCheckUpdates){
//Thread sleep 3 seconds
System.out.println("Do your thing here");
}
}
}
public void stop(){
shouldCheckUpdates = false;
}
Thread.stop is deprecated so how do we stop a thread in java ?
Always use interrupt method and future to request cancellation
When the task responds to interrupt signal, for example, blocking queue take method.
Callable < String > callable = new Callable < String > () {
#Override
public String call() throws Exception {
String result = "";
try {
//assume below take method is blocked as no work is produced.
result = queue.take();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
return result;
}
};
Future future = executor.submit(callable);
try {
String result = future.get(5, TimeUnit.SECONDS);
} catch (TimeoutException e) {
logger.error("Thread timedout!");
return "";
} finally {
//this will call interrupt on queue which will abort the operation.
//if it completes before time out, it has no side effects
future.cancel(true);
}
When the task does not respond to interrupt signal.Suppose the task performs socket I/O which does not respond to interrupt signal and thus using above approach will not abort the task, future would time out but the cancel in finally block will have no effect, thread will keep on listening to socket. We can close the socket or call close method on connection if implemented by pool.
public interface CustomCallable < T > extends Callable < T > {
void cancel();
RunnableFuture < T > newTask();
}
public class CustomExecutorPool extends ThreadPoolExecutor {
protected < T > RunnableFuture < T > newTaskFor(Callable < T > callable) {
if (callable instanceof CancellableTask)
return ((CancellableTask < T > ) callable).newTask();
else
return super.newTaskFor(callable);
}
}
public abstract class UnblockingIOTask < T > implements CustomCallable < T > {
public synchronized void cancel() {
try {
obj.close();
} catch (IOException e) {
logger.error("io exception", e);
}
}
public RunnableFuture < T > newTask() {
return new FutureTask < T > (this) {
public boolean cancel(boolean mayInterruptIfRunning) {
try {
this.cancel();
} finally {
return super.cancel(mayInterruptIfRunning);
}
}
};
}
}
After 15+ years of developing in Java there is one thing I want to say to the world.
Deprecating Thread.stop() and all the holy battle against its use is just another bad habit or design flaw unfortunately became a reality... (eg. want to talk about the Serializable interface?)
The battle is focusing on the fact that killing a thread can leave an object into an inconsistent state. And so? Welcome to multithread programming. You are a programmer, and you need to know what you are doing, and yes.. killing a thread can leave an object in inconsistent state. If you are worried about it use a flag and let the thread quit gracefully; but there are TONS of times where there is no reason to be worried.
But no.. if you type thread.stop() you're likely to be killed by all the people who looks/comments/uses your code. So you have to use a flag, call interrupt(), place if(!flag) all around your code because you're not looping at all, and finally pray that the 3rd-party library you're using to do your external call is written correctly and doesn't handle the InterruptException improperly.
I have a situation where I'm using a Thread, she call a method that will do multiple processes, I need to use a "cancel" button in which you have to stop the thread, I not can use: "while" ,to verify that it was canceled because it not has loop in this process.
Ex:
Task<Void> task = new Task<Void>() {
#Override
protected Void call() throws Exception {
controller = new FirstEtapaController();
execProcess();
return null;
}
};
new Thread(task).start();
Call Method
private void execProcess() {
Thread thread = new Thread(new Runnable() {
public void run() {
getController().execMhetod();
refreshTable();
}
});
thread.start();
thread.join();
};
Ie, I need to stop this process, even when the "ExecMethod" already running, it will take minutes, so I've gotta stop it and not have to wait for him to finish so that , others do not continues.
Remembering that this process will do iteration with my DAO.
The only way (well behaved way) is to add logic points in you spawned threads to check for an interrupted state. You can choose to use the built-in Thread.interrupt() mechanisms, or add your own logic using some form of thread-safe variable (an AtomicBoolean?) or a Semaphore of some sort.
If you use the Thread.interrupt() then your child processes will throw an InterruptedException when they encounter certain conditions, like Thread.wait() and other methods which require synchronization or use the java.util.concurrent.* classes.
You will need to (should already be) handle the InterruptedExceptions in the threads anyway, but perhaps you will need to put regular 'checks' in your child processes to look for the interrupted state anyway (can use Thread.isInterrupted() )
It is worth reading this Handling InterruptedException in Java
If instead of a raw Thread if you use an ExecutorService you'll end up with lots of additional methods/levers to control your threads, one of which is shutdownAll() which uses Thread.interrupt() to kill your thread and lets you check thread status via isTerminated()
Your user interface does not have to wait for the worker thread to finish, so don't worry too much about that.
Alas, Thread.destroy() and Thread.stop() are deprecated, due to bad implementations. I don't think there is a good "sig-kill" type of substitute for Java threads. You are going to have to recode the worker to check an abort flag of some kind, if it matters much. Otherwise, just let it waste a little CPU. ("you can't cancel that Save -- I've already done it!", in effect)
Whether or not a task can be canceled really depends on its implementation. Typically it intermittently checks a flag whether it should continue or not.
You can implement such a flag yourself, and a method to set it :
private volatile boolean shouldStop;
public void cancel() {
shouldStop = true;
}
#Override
public void run() {
while (!shouldStop) {
// do work
}
}
But threads already come with a flag : the interrupted flag. And while it is not necessarily used for canceling a thread, it is typical to use it for exactly that purpose. In fact the standard ExecutorService implementations will try to cancel their threads by interrupting them.
Aside from that several blocking methods (methods that put a thread in BLOCKED or WAITING state) will throw an InterruptedException when the thread is interrupted, at which point they become RUNNABLE again. This is something the previous approach with a boolean flag cannot achieve.
Therefore it is a better approach to use interruption to allow a task to be canceled. And you do not really need that cancel() method any more either :
#Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
// do work
}
}
As a bonus, any code that knows your thread, knows how to cancel it. Including standard ExecutorService implementations.
Care should be taken when catching an InterruptedException, since doing that clears the interrupted flag. It is adviseable to always restore the interrupted flag when catching the Exception, so clients also know it's time to stop doing what they're doing.
private BlockingQueue<Integer> queue;
#Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
Integer id = queue.take(); // blocking method
// do work
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
To cancel a thread, you can simply keep a reference to the Thread object and call interrupt() on it :
Thread thread = new Thread(new InterruptibleTask());
thread.start();
// some time after :
thread.interrupt();
But a more elegant approach is keeping tabs on your task (and not so much the specific thread it runs on) through a Future object. You can do this by wrapping your Runnable or Callable in a FutureTask.
RunnableFuture<Void> task = new FutureTask<>(new InterruptibleTask(), null);
new Thread(task).start();
// some time after :
task.cancel(true); // true indicating interruption may be used to cancel.
A Future is key in controlling your task. It allows you to wait for its completion, and optionally receive a value the task calculated :
try {
String value = future.get(); // return value is generically typed String is just as example.
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // since future.get() blocks
} catch (ExecutionException e) {
logger.log(Level.SEVERE, "Exception on worker thread", e.getCause()); // the ExecutionException's cause is the Exception that occurred in the Task
}
If you have several tasks (or even just one) it is worth using an ExecutorService :
ExecutorService pool = Executors.newCachedThreadPool();
Future<?> submit = pool.submit(new InterruptibleTask());
pool.shutdownNow(); // depending on ExecutorService implementation this will cancel all tasks for you, the ones Executors returns do.
This is the second post I have on trying to end/quit threads using interrupts and dealing with Ctrl-c ends. I'm not sure I understand it but here is my best attempt. I need more clarity on the concepts, and please give code examples where you can.
There are two classes, the main class Quitit and another class thething. The main class.
When loading the program via the terminal (the case on Linux):
Java -jar Quitit.jar
When you Ctrl-c to close it am i correct in saying that you need to:
Runtime.getRuntime().addShutdownHook()
Your threads so that they are killed on shut down.
Is this to correct way to deal with that ?
Why does it not allow you to call a method so that it may close down gracefully?
When not shutting down via Ctrl-C and you wish to do so via Thread.Interrupt() then does the program below use it correctly ?
Am I correct in saying that Thread.Join() halts the calling thread until the targeted thread is dead before continuing?
How would you implement/call the same Runtime.getRuntime().addShutdownHook() on implements Runnable threads, instead of extends Thread ?
Quitit class:
public class Quitit extends Thread {
public Quitit(String name) {
try {
connect("sdfsd");
} catch (Exception ex) {
}
}
void connect(String portName) throws Exception {
Thread thh = new thething("blaghname");
Runtime.getRuntime().addShutdownHook(thh);
thh.start();
System.out.println("Thread Thh (thething) Started()");
while (true) {
try {
Thread.sleep(2000);
if (thh.isAlive()) {
System.out.println("Thread Thh (thething) isAlive");
if (thh.isInterrupted()) {
System.out.println("Thread Thh (thething) is Inturrupted Should be Shutting Down");
} else {
System.out.println("Thread Thh (thething) is Not Inturrupted");
thh.interrupt();
System.out.println("Thread Thh (thething) Inturrput Sent");
System.out.println("Thread Thh (thething) Joined()");
thh.join();
}
} else {
System.out.println("Thread Thh (thething) isDead");
System.out.println("Main Thread:: can now end After Sleep off 2 seconds");
Thread.sleep(2000);
System.out.println("MMain Thread:: Sleep Ended Calling Break");
break;
}
} catch (InterruptedException xa) {
System.out.println("Main Thread:: ending due to InterruptException second Break called");
break;
}
}
System.out.println("Main Thread:: Outside While(true) via Break call");
}
public static void main(String[] args) {
try {
Thread oop = new Quitit("");
Runtime.getRuntime().addShutdownHook(oop);
oop.start();
} catch (Exception ezx) {
System.out.println("Main Thread:: Not Expected Exception");
}
}
}
TheThing class:
public class thething extends Thread {
thething(String name) {
super(name);
}
#Override
public void run() {
while (true) {
try {
System.out.println("thething class:: Inside while(true) Loop, now sleeping for 2 seconds");
Thread.sleep(2000);
} catch (InterruptedException e) {
try {
System.out.println("thething class:: has been Inturrupted now sleeping for 2 seconds!!");
Thread.sleep(2000);
break; // Will Quit the While(true) Loop
} catch (InterruptedException ex) {
System.out.println("thething class:: Second InterruptedException called !!");
}
}
}
System.out.println("thething class:: Outside while(true) and now thread is dying");
}
}
OutPut::
run:
Thread Thh (thething) Started()
thething class:: Inside while(true) Loop, now sleeping for 2 seconds
Thread Thh (thething) isAlive
Thread Thh (thething) is Not Inturrupted
Thread Thh (thething) Inturrput Sent
Thread Thh (thething) Joined()
thething class:: has been Inturrupted now sleeping for 2 seconds!!
thething class:: Outside while(true) and now thread is dying
Thread Thh (thething) isDead
Main Thread:: can now end After Sleep off 2 seconds
MMain Thread:: Sleep Ended Calling Break
Main Thread:: Outside While(true) via Break call
FINISHED - BUILD SUCCESSFUL (total time: 8 seconds)
I am surprised to here that control-c is not killing your program. It does on my test programs and should under most Unix variants.
When you Ctrl-c to close it am i correct in saying that you need to (setup a shutdown hook) so the threads are killed on shut down.
No, this is not correct. Shutdown hooks are used when you want to explicitly cleanup up some processing. They have nothing to do with the running threads and how they terminate.
Why does it not allow you to call a method so that it may close down gracefully?
Because that's not it's job.
Is this to correct way to deal with that ?
I'm not sure what the "that" is. As others have mentioned, the JVM finishes when the last non-daemon thread finishes. At that point the JVM kills all daemon threads and exits. If you want a background thread to be killed on shutdown then you'd do something like:
Thething theThing = new TheThing();
// set it to be a daemon thread before it starts
theThing.setDaemon(true);
theThing.start();
If you are asking about the proper way to terminate a thread cleanly then you can either use a volatile boolean or interrupt the thread. Typically this means that the class that starts the thread, keeps a handle around do it. Since QuitIt started TheThing class it would do something like the following if it was using a volatile boolean:
void connect(String portName) throws Exception {
Thread thh = new TheThing("blaghname");
thh.start();
...
// we are ready to kill the thread now
tth.shutdown = true;
}
Then in TheThing, the run() method would do something like the following:
public class TheThing extends Thread {
volatile boolean shutdown = false;
public void run() {
while (!shutdown) {
...
// you can also test for shutdown while processing
if (shutdown) {
return;
}
}
}
}
When not shutting down via Ctrl-C and you wish to do so via Thread.interrupt() then does the program below use it correctly ?
Using Thread.interrupt() is another way you can signal your thread that you want it to shutdown. You can also use the thread interrupt flag in a similar manner to the boolean above:
void connect(String portName) throws Exception {
Thread thh = new TheThing("blaghname");
thh.start();
...
// we are ready to interrupt the thread now
tth.interrupt();
}
It is very important to realize that interrupting a thread sets a flag on the Thread. They thread still needs to handle the interrupt appropriately with code. Then in TheThing, the run() method would do something like the following:
public class TheThing extends Thread {
public void run() {
while (!Thread.currentThread().interrupted()) {
...
}
}
}
Interrupting also causes wait(), notify(), and other methods to throw InterruptedException. The proper way to deal with this is:
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// catching the interrupted exception clears the interrupt flag,
// so we need to re-enable it
Thread.currentThread().interrupt();
// probably you want to stop the thread if it is interrupted
return;
}
Am I correct in saying that Thread.join() halts the calling thread until the targeted thread is dead before continuing?
Yes. Calling join() (with no arguments) will pause the calling thread until the thread it is joining on finishes. So typically you set your shutdown flag or you interrupt the thread and then join with it:
tth.shutdown = true;
// or tth.interrupt()
tth.join();
How would you implement/call the same Runtime.getRuntime().addShutdownHook() on implements Runnable threads, instead of extends Thread ?
This question doesn't make any sense. If you are asking about how to shutdown a thread if you have implemented Runnable, then the same mechanisms that I mention above would work.
Another thing that factors into the discussion of control-c is signal handlers. They allow you to catch control-c (and other signals) so you can do something intelligent with them. They are very OS dependent (of course) and if you catch the interrupt signal (SIGINT is usually sent by control-c) and don't stop the JVM, you are going to have problems.
But in any case, you can do something like the following:
...
MyHandler handler = new MyHandler();
// catch the control-c signal, "TERM" is another common kill signal
Signal.handle(new Signal("INT"), handler);
...
private static class MyHandler implements SignalHandler {
#Override
public void handle(Signal arg0) {
// interrupt your threads
// clean up stuff
// set shutdown flags
// ...
}
}
Again, I would say that it is a bad practice to catch interrupt signal (control-c) and not take the JVM down.
You have many questions in your question. If you want to gracefully shutdown threads when Ctrl-C is hit, then register a shutdown hook, and in the code of this shutdown hook, gracefully shutdown your threads.
A Thread instance can be constructed by extending Thread, or by passing a Runnable to the Thread constructor. So, if you want the code of your shutdown hook to be implemented in a Runnable, just do the following:
Runnable r = new Runnable() {
#Override
public void run() {
try {
// code of the shutdown hook: ask running threads to exit gracefully
for (Thread t : threadsToShutDown) {
t.interrupt();
}
for (Thread t : threadsToShutDown) {
t.join();
}
}
catch (InterruptedException e) {
// too bad
}
}
};
Runtime.getRuntime().addShutdownHook(new Thread(r));
Note that the above will prevent the JVM to exit if one of the threads doesn't respond to the interrupt. Introducing a timeout would be a good idea.
Also note that you must NOT start the thread that you register as shutdown hook.
When you Ctrl-c to close it am i correct in saying that you need to: Runtime.getRuntime().addShutdownHook() your threads so that they are killed on shut down.
No.
As per the docs, addShutdownHook simply registers a thread that will be run when the VM is shut(-ting) down. In theory this would be used as an application-wide finalizer; something that would run when your process is ending, to "tidy up". However there are some issues with them, similar to the reasons why finalizers are not recommended, in fact. They aren't guaranteed to run if the process is terminated abruptly, so they can't do anything critical. They run at a delicate part in the lifecycle, so they may not be able to access or interact with objects in a way that you'd expect. And they need to run quickly, else risk the process being killed before they finish.
But anyway this is completely different to what you're thinking of. When the VM shuts down, your threads will exit, without you needing to.
And besides, you have to provide an unstarted thread as a shutdown hook, so I'm slightly surprised that you don't get an IllegalThreadState exception thrown on shutdown.
When not shutting down via Ctrl-C and you wish to do so via Thread.Interrupt()
That's not the "usual" way to exit a multithreaded program either.
You have (broadly) two options:
Start your threads as "daemons", then just leave them be. The program exits when no non-daemon threads are running, so when your main thread terminates, your program will exit even though your "worker" threads are still alive. This works best of course when your
Signal to your threads that they should exit, e.g. call a stop() method that sets a boolean flag, and have those threads allow themselves to terminate. A thread stops when its run() method returns. Generally threads only keep running while they're in some sort of loop. Simply letting your thread exit the ongoing loop when its told to exit will shut it down gracefully, as typically it will finish its current "chunk of work" before checking the flag.
Interrupting a thread doesn't do what you might expect. It just sets another boolean flag internally. Many blocking operations (such as filesystem/network/database methods) will periodically check this flag and throw an InterruptedException if it is set. This allows a blocking method to exit early, but is not guaranteed if the method isn't "well-behaved".
So in your example it works because Thread.sleep() does respond to interrupts, and you then consider this a signal to exit. If however you write your own method to calculate the millionth Fibonacci number, for example, interrupting the thread would do nothing unless your implementation explicitly checks Thread.currentThread().interrupted() between each iteration.
Also, interrupts can come from almost anywhere, and it's hard to ascribe a particular "meaning" to them. Are they a signal to kill the thread? A signal to give up on the current method because the client's bored? A signal to start from the top because new data has arrived? In non-trivial programs it's not entirely clear.
A much better approach, given this, is to use boolean flags to communicate the reason, and then interrupt after setting the flag. A thread that gets interrupted should then check its state to see what just happened, and work out what to do. For example, you could code thething.run() as
private boolean keepRunning = true;
public void run() {
while(keepRunning) {
try {
System.out.println("thething class:: Inside while(true) Loop, now sleeping for 2 seconds");
Thread.sleep(2000);
} catch (InterruptedException e) {
try {
System.out.println("thething class:: has been Inturrupted now sleeping for 2 seconds!!");
Thread.sleep(2000);
} catch (InterruptedException ex)
{
System.out.println("thething class:: Second InterruptedException called !!");
}
}
}
}
And in QuitIt, set thh.keepRunning = false before interrupting it (or even better, define a method such as thh.allWorkDone() which sets the flag, and call that).
Note that there is no way to forcibly stop another thread - with good reason - you need to signal for the thread to stop, and ensure that whatever's running in the thread observes and respects that signal.
Best by huge margin - use daemon threads with no explicit termination. Next, redesign app so I can use daemon threads with no explicit termination. Absolute last resort, when no other approach is remotely possible, any kind of explicit shutdown code such has been posted here.
Thread currentThread=Thread.currentThread();
public void run()
{
while(!shutdown)
{
try
{
System.out.println(currentThread.isAlive());
Thread.interrupted();
System.out.println(currentThread.isAlive());
if(currentThread.isAlive()==false)
{
shutdown=true;
}
}
catch(Exception e)
{
currentThread.interrupt();
}
}
}
});
thread.start();
The alternative to calling stop is to use interrupt to signal to the thread that you want it to finish what it's doing. (This assumes the thread you want to stop is well-behaved, if it ignores InterruptedExceptions by eating them immediately after they are thrown and doesn't check the interrupted status then you are back to using stop().)
Here's some code I wrote as an answer to a threading question here, it's an example of how thread interruption works:
public class HelloWorld {
public static void main(String[] args) throws Exception {
Thread thread = new Thread(new Runnable() {
public void run() {
try {
while (!Thread.currentThread().isInterrupted()) {
Thread.sleep(5000);
System.out.println("Hello World!");
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
});
thread.start();
System.out.println("press enter to quit");
System.in.read();
thread.interrupt();
}
}
Some things to be aware of:
Interrupting causes sleep() and wait() to immediately throw, otherwise you are stuck waiting for the sleep time to pass.
Note that there is no need for a separate boolean flag.
The thread being stopped cooperates by checking the interrupted status and catching InterruptedExceptions outside the while loop (using it to exit the loop). Interruption is one place where it's ok to use an exception for flow control, that is the whole point of it.
Setting interrupt on the current thread in the catch block is technically best-practice but is overkill for this example, because there is nothing else that needs the interrupt flag set.
Some observations about the posted code:
The posted example is incomplete, but putting a reference to the current thread in an instance variable seems like a bad idea. It will get initialized to whatever thread is creating the object, not to the thread executing the run method. If the same Runnable instance is executed on more than one thread then the instance variable won't reflect the right thread most of the time.
The check for whether the thread is alive is necessarily always going to result in true (unless there's an error where the currentThread instance variable is referencing the wrong thread), Thread#isAlive is false only after the thread has finished executing, it doesn't return false just because it's been interrupted.
Calling Thread#interrupted will result in clearing the interrupt flag, and makes no sense here, especially since the return value is discarded. The point of calling Thread#interrupted is to test the state of the interrupted flag and then clear it, it's a convenience method used by things that throw InterruptedException.
Typically, a thread is terminated when it's interrupted. So, why not use the native boolean? Try isInterrupted():
Thread t = new Thread(new Runnable(){
#Override
public void run() {
while(!Thread.currentThread().isInterrupted()){
// do stuff
}
}});
t.start();
// Sleep a second, and then interrupt
try {
Thread.sleep(1000);
} catch (InterruptedException e) {}
t.interrupt();
Good way to do it would be to use a boolean flag to signal the thread.
class MyRunnable implements Runnable {
public volatile boolean stopThread = false;
public void run() {
while(!stopThread) {
// Thread code here
}
}
}
Create a MyRunnable instance called myrunnable, wrap it in a new Thread instance and start the instance. When you want to flag the thread to stop, set myrunnable.stopThread = true. This way, it doesn't get stopped in the middle of something, only where we expect it to get stopped.