What if Error is thrown from an executor's thread? - java

I have a single thread pool for task execution. As far as I know, continue working after OutOfMemoryError is occured is very dangerous. We should terminate our application if this happens. So, consider the following:
ExecutorService es = Executors.newSingleThreadExecutor();
es.submit(new Runnable() {
#Override
public void run() {
throw new OutOfMemoryError();
}
});
es.shutdown();
es.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS);
System.out.println("After throwing OutOfMemoryError");
In this code, we have the task throws OutOfMemoryError. But even after throwing it continues working and prints After throwing OutOfMemoryError.
Is it safe? I mean, we may end up with data corruption... Should we be prepared to this sort of scenarios and design tasks to terminate the application if Error is thrown?

What I suggest you do
retain and check the Future returned by es.submit this is where the Error is held.
always run a task with a try { doSomething(); } catch(Throwable t) { } so you can action any Error without having to check the Future object which you might have discarded.

There are two threads in the given example -- the main thread that starts the program and a thread for executing the specified tasks. All threads are allocated their own, independent from each other, stacks. However, all threads use the same memory heap. This is why the OutOfMemoryError effects the whole program, not just a single thread.
Generally speaking, upon termination (successfully or otherwise), the task executing thread does not effect execution flow of any other thread (unless this is what it was designed for doing). That is why, the main thread in the provided example, keeps running even though the task thread got terminated.
I would highly recommend studying the Java Concurrency in Practice book to get better overall undestanding of the Java concurrency and parallelism.

Related

How can I immediately terminate a Thread? (Not interrupt)

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.

How to stop / kill multiple threads after a Time-Out value in java

I want to stop / kill all Threads (Runnables) started by Main after a given timeout. I tried to do as mentioned below. But it is not working as expected. Apart from that, I tried with the Thread.interrupt() but the results is negative. I tried thread.stop(). It is working but deprecated.
Can anyone give some idea on this?
Note : I'm focusing on a solution for Runnables not Callables. And I'm trying to do this bymodifying only the client code (Main). Not the Threads (Supplier)
Main
Thread roxtoursThrd = new Thread(new Supplier("roxtours", 1));
Thread bluevacationsThrd = new Thread(new Supplier("bluevacations", 1));
Thread elixerThrd = new Thread(new Supplier("elixer", 1));
ExecutorService taskExecutor = Executors.newFixedThreadPool(4);
taskExecutor.execute(roxtoursThrd);
taskExecutor.execute(bluevacationsThrd);
taskExecutor.execute(elixerThrd);
taskExecutor.shutdown();
// taskExecutor.shutdownNow(); // This is also not stopping threads. They continue.
try {
taskExecutor.awaitTermination(1, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
Supplier.java
public class Supplier implements Runnable {
public Supplier(String name, int count) {
this.name = name;
this.count = count;
}
#Override
public void run() {
try {
// Some time consuming operations (URL Connections, XML Decoding, DB Queries etc etc) are goes in here.
} catch (Exception e) {
e.printStackTrace();
}
}
String name = null;
int count = 0;
Logger logger = Logger.getLogger(Supplier.class);
}
Making the executor's tasks respond to interruption will require changing the code for the Suppliers. Interruption is cooperative; the thread being interrupted gets a flag set on it, but it's up to the thread to decide how to handle it. If your Runnable doesn't act on it, as in your example, then nothing happens, the thread just keeps on executing.
The Executor can only cancel threads that respond to interruption, see the API documentation for ExecutorService.shutdownNow:
There are no guarantees beyond best-effort attempts to stop processing actively executing tasks. For example, typical implementations will cancel via Thread.interrupt(), so any task that fails to respond to interrupts may never terminate.
A thread can check its flag with the Thread#isInterrupted method. Your Runnable task should check Thread.getCurrentThread().isInterrupted().
If a thread is waiting or sleeping when the interrupted flag is set then an InterruptedException will be thrown and the flag will be cleared.
Do not use Thread#setDaemon(true) unless you're prepared for those threads to disappear suddenly with no warning and no chance to clean up pending tasks when the rest of the application shuts down.
The other option is the deprecated Thread#stop method, which causes ThreadDeath to be thrown. Unlike interruption, this is not cooperative, and it's between difficult and impossible to write code that can predictably and cleanly terminate when this exception occurs, because ThreadDeath can be thrown anywhere, unlike InterruptedException, which is much more manageable since it is only thrown from specific blocking calls.
Use shutdownNow() instead of shutdown().
The shutdown() will initiate the shutdown and it will not accept any new tasks but you never know when the threads will be actually stopped.
The shutdownNow() will immediately attempts to stop all the active threads and this will return all the active threads which are awaiting for execution.
Again there is no guarantee that all the threads will be stopped immediately (Threads will go for a graceful shutdown and it may take time based on the task given to the thread). We have to use either of the below methods to wait till all the threads are completed its execution.
executor.awaitTermination(...);
or
while (! executor.isTerminated()) {
// Sleep for few milliseconds...
}
Refer the doc: http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorService.html#shutdown%28%29
Your thread's run method is not blocking, hence it does not run into a situation where an InterruptedException is thrown.
When a Thread is inerrupted, besides throwing an exception if it is blocking, it also has its interrupted status set, that is to say the method Thread#isInterrupted() returns true. Also, the method Thread#interrupted also returns true, but with the latter the interrupted status of the thread is cleared.
In your example you are not blocking nor are you checking the threads inerrupted status.
EDIT: Since you are not checking to see if the thread is interupted nor are you blocking, then you can't stop the threads explicitly, but you can stop them by making them daemon threads and then when your main thread (which is a user thread) finishes, all the other daemon threads will stop. Main difference between daemon thread and user thread is that as soon as all user thread finish execution java program or JVM terminates itself, JVM doesn't wait for daemon thread to finish there execution.
If you want to interrupt threads, you have to provide interruption entrance point. Sleep for a very short time, for example, then catch and handle InterruptionException.
Next what you can do is make use of isInterrupted() method in every iteration and the handle that as well.
Other approach would be to make all the threads daemons with setDaemon(), as they would be killed after main thread finishes, but this would be useful only if main was to be stopped.
In response to your edit/updated question:
excerpt from shutdownNow() documentation
There are no guarantees beyond best-effort attempts to stop processing
actively executing tasks. For example, typical implementations will
cancel via Thread.interrupt(), so any task that fails to respond to
interrupts may never terminate.
So either you prepare you application to work as multi-threaded or you stick to single thread.
Also, see How do you kill a thread in Java?.
And the most important link from the question above: http://docs.oracle.com/javase/1.5.0/docs/guide/misc/threadPrimitiveDeprecation.html

Monitor thread status

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.

Java thread still in memory after being shutdown

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

Java strange thread termination

I have a system with multiple threads running - my main-thread just checks if there are jobs to be done and if there are some, it calls the sub-threads (notifyAll()) who will execute it. After that, the sub-threads just wait() until there are some new tasks.
Actually, the thread-system is running reliable, but after a longer runtime (3-5h), some sub-threads just die without a warning or an error. They just exit one after another - but again only with a time-range of 2-x hours. I have used jconsole to check this phenomenon, which threads are running and how they just simply disappear.
Furthermore, the main-thread is executing every second, but the sub-threads are mainly wait()ing and are not often used at all (since there are not so many tasks in the test environment).
The only reason I can think of is, that the JVM turns off the sub-threads since they are not often used enough?
I would be very thankfull for your help!
P.S. All threads are not defined as daemons and the main-thread just works fine!
edit
Thanks for your answers, but I actually use this loop.
public void addTask (Task in_task) throws InterruptedException {
synchronized (tasks) {
while (tasks.size() == MAXIMUM_NUMBER_OF_TASKS) {
tasks.wait();
}
tasks.offer(in_task);
tasks.notifyAll();
}
}
I use this loop, so that only some speciall amount of tasks will be executed.
The documentation for Object.wait() says:
As in the one argument version, interrupts and spurious wakeups are possible, and this method should always be used in a loop:
synchronized (obj) {
while (<condition does not hold>)
obj.wait();
... // Perform action appropriate to condition
}
Maybe you didn't follow this advice and got a spurious wakeup or interrupt?
Instead of writing your own multi-threaded task execution solution you could use java.util.concurrent.ThreadPoolExecutor. This would probably be a good idea no matter whether you are able to fix this bug or not.
I recommend using one of the Executors for managing your tasks. There are less chances that you will lose a possible error or exception in one of you sub-threads, so it should help you debug you program. Any exception that happens in a sub-thread will be stored inside the Future object and rethrown as an ExecutionException when you call Future#get().
List<Future<Void>> taskResults = new ArrayList<Future<Void>>();
ExecutorService es = Executors.newFixedThreadPool(NUMBER_OF_THREADS);
while(!finished){
//say you wait (blocking) for a new task here
Callable<Void> task = getNextTask();
//put the task into the pool
Future<Void> result = es.submit(task);
taskResults.add(result);
}
//3 hours later, set `finished` to true
//at the end check that no exceptions were thrown
for(Future<Void> result : taskResults){
try{
result.get();
}catch(ExecutionException e){
//there was an error
e.getCause().printStackTrace();
}catch(InterruptedException e){
//irrelevant
}
}
In general, stuff in the java.util.concurrent helps you write much more robust multi-threaded applications, without having to resort to Object#wait() and other concurrency primitives (unless you are learning, of course).
Try setting an uncaught exception handler on each thread.
There is a setUncaughtExceptionHandler() function on the Thread. Implement the UncaughtExceptionHandler interface and print the exception.
General idea, but don't do it with anonymous classes/methods:
thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler()
{
public void uncaughtException(Thread t, Throwable e)
{
e.printStackTrace();
}
});

Categories

Resources