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.
Related
I'm pretty new to Scala/Java and have to build a service that will have at least two sub-services running: a socket-based subscriber that listens for messages to kick off workers, and a web server that will serve a status page for those workers.
I can get these things to run, but after both start the whole process immediately exits with code 0.
I did some research to learn about user threads vs daemon threads in Java, as well as threading in general, so now my approach is basically this:
val webServerThread = new Thread(WebServer(config)).start()
val subscriberThread = new Thread(Subscriber(config)).start()
val aliveThread = new Thread(keepAlive(true)).start()
The third thread simply contains a while(true){} block to leave a user thread up.
There has to be a smarter way of doing this, but I don't know what it is and seems impossible to discover. How do http server's stay running, for example? Is there a while(true) loop underneath every framework out there?
Any help would be appreciated.
The run() method of the thread would have to be an endless loop, until some condition occurs and you exit the loop.
To wait for a thread to exit, the way to do that is as follows:
final Runnable runnable = new Runnable() {
public void run() {
// do stuff
}
};
final Thread thread = new Thread(runnable);
thread.start();
try {
thread.join();
} catch (final InterruptedException e) {
// deal with exception
}
Obviously, that will only wait for one thread. It depends on your scenario whether this makes sense. Alternatively, you could use a ThreadPoolExecutor, invoke the shutdown() or shutdownNow() method, and use awaitTermination for it to stop.
So for all services that have to stay running, say a web server or something, is there some code somewhere that just is basically while(shouldRun) {//nothing}?
No. There is never any reason to have a JRE thread that does nothing, and a thread that uses 100% CPU while accomplishing nothing would be even worse.
Pretty much every thread in a program should sit in a loop, waiting for something to do.* E.g., An I/O thread that waits to receive and process input from some external source, a pool thread that waits for tasks to perform, a scheduler thread that waits until it's time to perform the next scheduled task.
A web service must have at least one thread that sits in a loop and waits to handle incoming connections. I don't remember how to write that without doing some research first because there are so many open-source web servers out there: There's no reason to write your own except for practice. There is even one built-in to the Oracle JRE.** In pseudo code, it might look like this:
while (! time_to_shut_down) {
connection = WaitForIncomingConnection();
clientThreadPool.handle(connection);
}
I can get these things to run, but after both start the whole process immediately exits with code 0.
I do not know why your program won't stay running. I am not familiar with Scala or, with the WebServer class or the Subscriber class.
What is config? Maybe somebody would be able to help you if you would ammend your question to show how you create the configuration object.
*One exception to that rule would be a compute-thread in a program that performs a single, massive computation and then exits.
**See https://stackoverflow.com/a/3732328/801894. The server.start(); call in that example is what kicks off the service thread. And, notice that the main() thread terminates right after it starts the server thread.
This is not a question about how to cleanly terminate a thread, ie by calling interrupt on it and having the thread respond appropriately. I cannot modify code the thread is executing in any way.
I specifically want to immediately terminate a Thread, I don't care at all what state things are left in. I know something similar is possible using Thread.stop, however this actually throws a ThreadDeath exception, and for the Thread to terminate this exception cannot be caught. However the code I am dealing with catches this exception and is not rethrowing it.
Thread.destroy() seemed to be what I was looking for, however this method was never implemented. Is there any other way of achieving this?
I believe that there's no way in Java to just kill off a thread like you're describing. As you note in a comment, interrupt won't do what you want. If the thread is executing, it just sets a flag and it's up to the thread to notice it. if the thread is waiting or sleeping, it will throw an InterruptedException.
The only way I can imagine doing what you're describing is to kill the process in which the thread is running. (E.g., call System.exit(int).)
No there isn't a way. From Java Concurrency in Practice:
Since there is no preemptive way to stop a thread, they must instead
be persuaded to shut down on their own.
Interrupting a thread is not the cleaner way as you said. Clean ways could be:
ExecutorService.shutdown()
Future.cancel()
Poison Pills
You aren't meant to submit tasks to threads that take ages to be done. You would rather divide them into smaller tasks and send a poison pill to cancel the bigger task. If there is not a way to do that, then spawn/fork a process and kill it if you want to cancel the task.
If you don't trust the thread in question to the point that you need to kill it, you would probably be better off running it in a separate process, and kill the process instead.
Anyway, the following code might work if you are ok with the deprecated Thread methods:
while (theThread.isAlive()) {
theThread.stop();
}
Depending on how badly the thread is trying to survive…
You might want to run this code in several threads or repeat the stop() call if that's not enough. However, I managed to kill the following thread with this code:
final Thread iWontDie = new Thread(() -> {
int i = 0;
while (true) {
try {
System.out.println("I'm still alive! " + ++i);
} catch (Throwable t) {
// eat t
}
}
});
iWontDie.start();
If you are on Java 7 or earlier, you could use the overloaded stop(Throwable obj) method to throw something besides a ThreadDeath error:
Forces the thread to stop executing. If the argument obj is null, a NullPointerException is thrown (in the current thread). The thread represented by this thread is forced to stop whatever it is doing abnormally and to throw the Throwable object obj as an exception. This is an unusual action to take; normally, the stop method that takes no arguments should be used.
This method, like the parameterless version, is deprecated, so just keep that in mind.
I have a class XYZ which extends Thread and it is also a singleton (Yes. My application needs that).
In the run method, I have something like this:
public void run() {
service.start();
}
The time it takes for service.start() is huge.
Also, my application will not always need the thread to be run but can't decide in advance so while launching the application I am starting this thread.
Now, when application doesn't need the thread, it gets completed very quickly and all I need to do is wait for thread to die.
I tried to use stop() method but came to know that it is deprecated.
See this article for alternatives to calling stop()
http://docs.oracle.com/javase/1.5.0/docs/guide/misc/threadPrimitiveDeprecation.html
stop has been deprecated a long time ago and should not be used. Thread termination is a cooperative process in Java (i.e. the interrupted code must do something when asked to stop, not the interrupting code) - one way is to call thread.interrupt() on the thread you need to interrupt.
You then need to catch the generated interrupted exception in the running thread or check the interrupted status regularly. Once the running thread detects that is should stop what it's doing, you can then run any cleanup tasks as required and exit whatever you were doing.
Signal your thread to do it's cleanup stuff, which you said is fast anyway, then just do a Thread.join.
Your question is highly dependant on exactly what is going on in service.start(). If it's opening external resources, then naturally you can't just barge in and kill the thread without proper cleanup. The start procedure will need to be coded explicitly for interruptibility with proper cleanup.
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.
I need a thread to wait until a file is exist or created.
I have the following code so far:
while(!receivedDataFile.isFileExists("receiveddata.txt"))
{
try {
Thead.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
return null;
}
}
When I run it, the following exception appears, and the thread ends:
java.lang.InterruptedException: sleep interrupted
A thread is interrupted when it is blocking (the call to sleep) and another thread calls its interrupt method. The call to interrupt must be made explicitly for this to happen.
Seems that repeating the check for the file would be the logical thing to do if the thread is interrupted, but without knowing the cause of the interruption it's hard to say.
As usual, when it comes to threading, Brian Goetz has something to say on the matter of InterruptedException:
http://www-128.ibm.com/developerworks/java/library/j-jtp05236.html
I must agree Bombes comment: threads don't get interrupted on their own. Contrary to Jokis comment - they're not interrupted when a thread context swap takes place either (in fact, if a thread sleeps, it will surrender it's quantum to any thread that has work to do, but I digress).
Furthermore, I would advise an alternative means of communication than polling for files. You cannot be certain, for example, that once you have spotted a file, that it has been completely written without extra work from the file-writer (such as renaming it when ready, or creating a 'ready' file).
Consider using something more 'data push' such as RMI, HTTP-POST, JMS queues, etc.
You should find out which thread interrupts that thread. Threads don’t do that on their own.
If all you want is a notification when a file is created, AND you can (and willing) to go native (JNI) AND you want only win32 support, you could use the code here.
Well, if you don't know what InterruptedException is and/or don't want to do anything about it, obviously you should at least do something besides returning and exiting your loop. Take out the return, and then you'll keep waiting.
But I'd check into why you're getting interrupted. Something is trying to cancel your thread.