I have a multi-threaded program, where I have one thread to watch over several threads. The functioning is designed like this:
Main program does initiation and starts Watcher Thread, in void Main(), I have the line
Runtime.getRuntime().addShutdownHook(new Thread(new ShutdownThread(), "Exit Listener"));
When I don't start the watcher thread, the ShutdownThread is called when I terminate the program, but when I start the Watcher thread which has a dead loop in it, the ShutdownThread is not called (I print out a message in that thread). That is very very strange. Any explanations?
The watcher thread is like:
public void run(){
boolean running=false;
thread a=new thread(...); //Do the same thing for b, c, d...
while(true){
if (a.isActive()){
if (running)
thread a= new thread(...);
a.start();
running=true;
}
Thread.sleep(1000); //try catch block...
}
What I would like is a graceful shutdown, that upon getting a terminate signal, shutdownThread is run, sets a flag and interrupts all threads, and waits for the threads to interrupt it, or it timeout so that the remaining threads can be killed. All the threads can catch an interuption, and check if a flag is set, if set, it will interrupt shutdownThread and then exit itself. Instead what I am seeing is all the threads are terminating by itself, doing no cleanup at all.
How about using signals? Is there any good cross-platform code for that?
Then, setUncaughtExceptionHandler doesn't work either. I did testing, and found that the handler isn't called at all. I don't know why. The code for the handler is:
public static class ErrHandler implements Thread.UncaughtExceptionHandler{
public final void uncaughtException(Thread t, Throwable e) {
Error(t + "died, threw exception: " + e);
}
}//this is in public class globals
I hook it using
producer.setUncaughtExceptionHandler(Globals.errhandler);
Is in my code, and I only see the original e.printStack() instead. It seems that I can't override it, either in the parent thread, or in itself. This is so frustrating. I'm thinking of putting a Entry into a queue, and reading it elsewhere. At least that may work.
Oh, the whole purpose is to make sure that if any of the threads die because of runtime exceptions, the watcher thread will check whether the exception is fatal enough, and decide to restart that thread or to quit altogether. At the same time, I would like the program to end gracefully (an interrupt is sent to saver threads so that it dumps the results out, and then interrupts back to tell that we are ready to quit) when the user ends it.
Dunno if it helps you, but we encountered the same behaviour.
Not all exceptions are routed correctly to the registered ExceptionHandler.
I wonder if Unit-Tests exists at all for the concurrent framework. Because this had to be detected.
We implemented the ScheduledExecutorService by ourself by using a ScheduledExecutorService instance as delegate and encapsulate the parameter Runnable/Callable of each method in a Runnable/Callable implementation which corrects the behaviour.
Related
So I have this very relevant thread I start when the program starts.
The thread is listening to events coming from a bigger system as the main thread does other stuff.
The thread should never stop working and if it does, it should be recreated and started.
I think I know multiple ways to achieve this, but I'd like to know your opinion on some things :
Am I just striving for nothing? I mean, if I ideally try-catch all the code that can go wrong, will the thread ever betray me for no obvious reason?
What's the best practice to do what I stated? Periodically check the thread health with another thread and a ScheduledExecutor? Implement some kind of observable-observer pattern?
You can create the ExecutorService which is listening to the events via Executors.newSingleThreadExecutor().
In that case You don't have to take a look at the thread if it is healthy, the ExecutorService takes care of that. The SingleThreadExecutor is responsible that only one Task (Runnable or Callable) is running at one time.
If you are checking using normal Java provided methods to view the thread state correctly, you should not have any errors. In the case that a checked exception is thrown or the thread exits for some weird reason, a try-finally block should be sufficient to start a new thread (also ensure it is non-daemon). You could use a while loop with a periodic pause, preferably using a thread scheduling mechanism such as timed wait(...), or timed LockSupport#park(...). You can also sleep the thread as well.
The thread should never stop working and if it does,...
OK, so write it so that it will never stop working.
public void run() {
while (true) {
try {
Message message = receiveNextMessage();
handleMessage(message);
} catch (Exception ex) {
LOGGER.error(ex);
if (somethingTrulyHorribleHasHappened(ex)) {
Runtime.getRuntime().exit(1);
} else {
maybeResetSomethingThatNeedsToBeReset();
}
}
}
}
This is a somewhat pointless and futile exercise. An app-lifetime thread should be debugged and made to not stop. The main thread of your app lasts for the process lifetime and any other threads should be designed, tested and debugged to the same standard.
What would happen if the thread that stopped had corrupted data in other threads when it crashed? If you just restarted it somehow, the data corruption may well make the situation worse.
Occasionally we must forcibly stop a thread as a best effort before entirely shutting down the whole JVM. Usually Thread#stop is cited as a surefire, even if ham-handed and deprecated, way to unconditionally stop a thread. This is not so, however: all the rogue thread has to do to keep itself running is catch ThreadDeath or a superclass:
public static void main(String[] args) throws InterruptedException {
final Thread t = new Thread() { public void run() {
for (;;)
try { Thread.sleep(Long.MAX_VALUE); }
catch (Throwable t) {
System.out.println(t.getClass().getSimpleName() + ". Still going on...");
}
}};
t.start();
Thread.sleep(200);
t.interrupt();
Thread.sleep(200);
t.interrupt();
Thread.sleep(200);
t.stop();
Thread.sleep(200);
t.stop();
}
This will print
InterruptedException. Still going on...
InterruptedException. Still going on...
ThreadDeath. Still going on...
ThreadDeath. Still going on...
Is there anything else that I could do to really, really stop a thread without killing the whole JVM?
No. There is no built in simple way to really stop a thread.
Such a method, destroy, was planned but not implemented:
Deprecated. This method was originally designed to destroy this thread without any cleanup. Any monitors it held would have remained locked. However, the method was never implemented. If if were to be implemented, it would be deadlock-prone in much the manner of suspend(). If the target thread held a lock protecting a critical system resource when it was destroyed, no thread could ever access this resource again. If another thread ever attempted to lock this resource, deadlock would result. Such deadlocks typically manifest themselves as "frozen" processes.
Threads are not meant for that. They don't provide security. The other thread could just as well terminate the JVM itself - or spawn other problematic threads.
For more information, see Why are Thread.stop, Thread.suspend and Thread.resume are deprecated. You can read why here.
There is no way to guarantee that that thread can be stopped in Java. The most forceful way is Thread.stop but that's an accident waiting to happen. The alternatives are to use Thread.interrupt and having the thread check a flag but both of these rely on the thread being coded correctly and, in the case of the flag, checking it on a regular basis.
Personally, I would make sure I wasn't catching ThreadDeath. Stop is a poor way to stop a thread but at least you should get a notification as long as you aren't catching ThreadDeath.
instead of continuous checking of variable inside a loop:
class Tester {
public static void main() {
Try t = new Try();
Thread.sleep(10); //wait for 10 milliseconds
t.interrupt(); // 'interrupt' i.e stop the thread
}
}
public class Try extends Thread {
public void interrupt() {
//perform all cleanup code here
this.stop();
/*stop() is unsafe .but if we peform all cleanup code above it should be okay ???. since thread is calling stop itself?? */
}
}
In order to perform interrupt in a good manner you should poll for the "interrupted()" method inside the thread that is being interrupted.
Just be aware that calling interrupted() method resets the interruption flag (that is set when calling interrupt()).
I guess the bottom line is that you have to continuously poll inside the thread in order to perform a graceful interruption.
You should never ever call .stop() on a Thread, period. It's not enough for the thread to perform its own cleanup. Since calling .stop() immediately releases all monitors, other threads may see shared data in an inconsistent state which may result in almost impossible to track errors.
Use Thread.interrupt() method instead of Thread.stop(). In the interrupted thread you can catch the InterruptedException and do any cleanup required.
A similar questions has already been asked here, you can find a code sample there too.
Could some help me fix this. The code below is what I am using to start/stop some Polling service. The Polling service operates with a while(boolean running) loop. Calling Polling.setRunning(false) would terminate the loop.
private static ExecutorService pool = Executors.newSingleThreadExecutor(new ThreadFactory() {
#Override
public Thread newThread(Runnable runnable) {
Thread thread = Executors.defaultThreadFactory().newThread(runnable);
thread.setDaemon(true);
return thread;
}
});
public static void start(){
pool.submit(new Runnable() {
public void run(){
try{
System.out.println("Starting Polling...");
Polling.start();
} catch(Exception e){
e.printStackTrace();
}
}
});
}
public static void stop(){
System.out.println("Stopping Polling...");
Polling.setRunning(false);
pool.shutDownNow();
}
public static void main(String[] args) throws Exception {
start(); //call to start
Thread.sleep(5000);
stop(); //call to stop
}
Question is: when I run this everything works fine and as expected. However, when I run:
ps -ef | grep java it shows that the program is still running in background. Even though the polling service has definitely stopped!
Why does this happen? And what can I do to fix it?
You need to take a thread dump to see which non-daemon threads are still running.
jstack, visualvm or jconsole are a few ways to do this.
You can force the application to stop with
System.exit(0);
As polling is in a daemon thread it won't matter if its stopped or not. The program would finish regardless.
IMHO, you should not roll your own boolean flag. Instead, use the thread's own interrupted status.
while(!Thread.currentThread().isInterrupted()){
// do stuff
}
If you read the javadoc concerning shutdownNow(), it says
... any task that fails to respond to interrupts may never terminate
I believe this would not be the case if you implemented the above logic. Also, if you perform any blocking operations, you'll need to propagate the interruption to ensure that the thread receives the interrupt.
In your processing, are you catching Exceptions and continuing processing? Are you not allowing the ThreadInterruptException to trickle up and cause the Thread to shut down?
http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/ExecutorService.html#shutdownNow()
If you are seeing that the Java process is alive, it is because there is atleast one daemon thread in the JVM. The API documentation of the Thread class states:
The Java Virtual Machine continues to execute threads until either of
the following occurs:
The exit method of class Runtime has been called and the security
manager has permitted the exit operation to take place.
All threads that are not daemon threads have died, either by
returning from the call to the run method or by throwing an exception
that propagates beyond the run method.
And therefore, this line of code in your ThreadFactory implementation ought to explain why the process continues to be alive:
thread.setDaemon(true);
All Runnable tasks that are submitted to the ExecutorService will now be run as daemon threads. You ought to verify whether the threads that have been initialized have been terminated or not. This also includes the thread that is executes your polling loop (and need not be the main thread, depending on how you've written the Polling class).
If you've reviewed your code and you haven't figure out what section is responsible for the daemon thread to be alive, you adopt one of the following techniques to determine what thread is preventing the JVM from shutting down:
Send a SIGQUIT signal to the Java process. This will give you a thread dump of the JVM, with the stacks of all the threads; you will need to redirect stdout to a file, in case your JVM process is running as a background process. In the resulting stack trace, you should find at least one daemon thread that is alive and executing a section of code in your application.
Consider setting a name to the threads initiated by the ThreadFactory. This way, should you use a logger that prints out the thread name along with a message at the end of the run method, you can determine whether threads are alive by noting the absence of any messages.
Are you using any blocking queue or any resource? Because how normally it works is that, when you call up shutDownNow(), it throws an interrupt to the thread, if the pool thread hasnt started executing the Runnable, it terminates, if not then it has to wait till the end.
Now the point is if you are using a BlockingQueue or Asynchronous I/O with Selector or whatever, each has its own policy of how it deals with interrupts. Say if you used a BlockingQueue, and say it was is waiting for a Runnable, and at the same moment an interrupt is received, then it throws an InterruptedException and the interrupt status is cleared.
ie you will have manually let the stack know, that an interrupt was thrown by:
try{
runnable.run();
}
catch(InterruptedException ex)
{
Thread.currentThread.interrupt();//let the stack know that interrupt was thrown.
}
If your case is the above case, without the catch statement, the thread will never terminate, because the interrupt status is cleared as soon as the Exception was thrown.
Hence depending on the package you use, check the interruption policy.
It will be better if you can provide the code in Polling
Lets say i am in the main method calling a process. Now if this process is stuck or taking too long, normally one can interupt it by interupting the thread.
But incase i have it implemented in the main method not in any external thread, how can i call that current thread itself for interuption like we call say thread.interupt();
Please back up a second. Thread.interrupt only interrupts wait conditions, not computations. There is no Java construct (except the monitoring/debugging agents) for interrupting a computation.
So, if you want a long-running computation to be interruptible, you have to write it to carefully check for interrupts every so often.
If you want to be able to 'interrupt' from outside the process altogether, you will need to handle signals. That's about the only interpretation I've been able to place on your question about the main thread.
This blog post (not mine) has the basic information. From a handler, you could interrupt, for example, the main thread.
You can let another thread interrupt "you" (main). Like this:
final Thread me = Thread.currentThread();
Thread wake_me_up = new Thread(){
#Override
public void run(){
//InterruptionException try catch omitted.
Thread.sleep(200);
me.interrupt();
}
};
wake_me_up.start();
try{
go_into_cave();
}catch(InterruptedException e){
//I got interrupted
System.out.println("thank you, you saved my life");
}
go_home();
While I find it hard to read...
In the main method, you'll have a reference to all Threads. Just get the right reference and do something like this
someThread.interrupt();
Make sure you don't forget to check if the Thread that is running got the flag to interrupt set true.
For example, in the middle of it's method, it needs to be checked if itself isInterrupted() by some Thread else
if(Thread.currentThread().isInterrupted()){
doSomeStuff();
}
You can create a new Thread and call your process from inside the new Thread. Interrupt this thread and catch the exception as per your logic.
I am not sure how to do it only form within the main method, but if your process call is called through a method, just call this method from a new thread and put up a timer in the main method. Once the timer expires, interrupt that thread and you're good to go.
If you're trying to kill the process, because it's hung, why are you even worrying about the thread? Runtime.exec() returns a Process object, which you can use to destroy the subprocess. You should be able to:
Spawn the subprocess, saving the Process object.
Presumably, you're reading the output stream of the process, via what is returned by
Process.getInputStream(). So, continue to do that.
However, spawn a second thread (or use the main thread) to monitor the process. If it
decides that the process has run too long, it can kill it via Process.destroy().
At that point, the first thread should get an EOF or an IOException (stream closed) on
the process's output stream.