I know that finally blocks in deamon threads would not be executed. But my meticulous nature tries to understand why and what happens in JVM so special that it could not call the code under this block.
I think that it somehow related to call stack that it whould not unwind, but don't know how. Can someone please shed some light on this.
Thanks.
Who says that finally blocks in daemon threads don't execute? This is not true in general.
What you might have heard that a finally block is not guaranteed to be executed when a JVM is shut down during the execution of the try (or catch) block. That is correct (and it can easily happen to daemon threads).
But again: during normal operation, there is nothing that stops finally blocks from executing normally in daemon threads: they are not handled differently.
The shutdown problem is easy: when the JVM is asked to shut down or even forced to shut down, then it may simply not be able to execute any more statements.
For example, on POSIX-y operating systems, signal 9 (SIGKILL) forces an application to quit, giving it no chance to do any cleanup (this is why signal 15 (SIGTERM) is preferred, usually). In this case, the JVM can't execute the finally block, because the OS won't let it run any longer.
If the JVM exits while the try or catch code is being executed, then the finally block may not execute.
Normal Shutdown - this occurs either when the last non-daemon thread exits OR when Runtime.exit()
When a thread exits, the JVM performs an inventory of running threads, and if the only threads that are left are daemon threads, it initiates an orderly shutdown. When the JVM halts, any remaining daemon threads are abandoned finally blocks are not executed, stacks are not unwound the JVM just exits. Daemon threads should be used sparingly few processing activities can be safely abandoned at any time with no cleanup. In particular, it is dangerous to use daemon threads for tasks that might perform any sort of I/O. Daemon threads are best saved for "housekeeping" tasks, such as a background thread that periodically removes expired entries from an in-memory cache.
Last non-daemon thread exits example:
public class TestDaemon {
private static Runnable runnable = new Runnable() {
#Override
public void run() {
try {
while (true) {
System.out.println("Is alive");
Thread.sleep(10);
// throw new RuntimeException();
}
} catch (Throwable t) {
t.printStackTrace();
} finally {
System.out.println("This will never be executed.");
}
}
};
public static void main(String[] args) throws InterruptedException {
Thread daemon = new Thread(runnable);
daemon.setDaemon(true);
daemon.start();
Thread.sleep(100);
// daemon.stop();
System.out.println("Last non-daemon thread exits.");
}
}
Output:
Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Last non-daemon thread exits.
Is alive
Is alive
Is alive
Is alive
Is alive
I have created two non-daemon threads which will terminate before the rest two daemon threads.
One non-daemon thread wait for 20 sec,
one daemon thread wait for 40 sec,
one non-daemon thread sleep for 15 sec,
one daemon thread sleep for 30 sec,
one daemon thread sleep for 10 sec. The idea to terminate non-daemon threads before some daemon ones.
As the result suggests, the JVM will terminate as soon as there is no non-daemon thread alive, without executing the rest statements in the Runnable tasks of the daemon threads, even if they are inside finally block without throwing InterruptedException.
public class DeamonTest {
public static void main(String[] args) {
spawn(40000, Action.wait, true);
spawn(30000, Action.sleep, true);
spawn(10000, Action.sleep, true);
spawn(20000, Action.wait, false);
spawn(15000, Action.sleep, false);
}
enum Action {
wait, sleep
}
private static void spawn(final long time, final Action action,
boolean daemon) {
final Thread thread = new Thread(new Runnable() {
#Override
public void run() {
Thread thread = Thread.currentThread();
try {
switch (action) {
case wait: {
synchronized (this) {
System.out.println(thread + " daemon="
+ thread.isDaemon() + ": waiting");
wait(time);
}
break;
}
case sleep: {
System.out.println(thread + " daemon="
+ thread.isDaemon() + ": sleeping");
Thread.sleep(time);
}
}
System.out.println(thread + " daemon=" + thread.isDaemon()
+ ": exiting");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.println(thread + " daemon=" + thread.isDaemon()
+ ": finally exiting");
}
}
});
thread.setDaemon(daemon);
thread.start();
}
}
Related
final ExecutorService executor = Executors.newFixedThreadPool(1);
final Future<?> future = executor.submit(myRunnable);
executor.shutdown();
if(executor.awaitTermination(10, TimeUnit.SECONDS)) {
System.out.println("task completed");
}else{
System.out.println("Executor is shutdown now");
}
//MyRunnable method is defined as task which I want to execute in a different thread.
Here is run method of executor class:
public void run() {
try {
Thread.sleep(20 * 1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}}
Here it is waiting for 20 second but when i run the code it throws an exception:
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
I am not able to close the concurrent thread ruining in Java Executor class. Here is my Code flow:
Created a new Thread with Java executor class to run some task i.e written in MyRunnable
executor wait for 10 second to complete the tasks.
If the task has completed then runnable thread also got terminated.
If the task is not completed within 10 second then executor class should terminate the thread.
Everything works fine except the termination of tasks in the last scenario. How should I do it?
The shutDown() method simply prevents additional tasks from being scheduled. Instead, you could call shutDownNow() and check for thread interruption in your Runnable.
// in your Runnable...
if (Thread.interrupted()) {
// Executor has probably asked us to stop
}
An example, based on your code, might be:
final ExecutorService executor = Executors.newFixedThreadPool(1);
executor.submit(new Runnable() {
public void run() {
try {
Thread.sleep(20 * 1000);
} catch (InterruptedException e) {
System.out.println("Interrupted, so exiting.");
}
}
});
if (executor.awaitTermination(10, TimeUnit.SECONDS)) {
System.out.println("task completed");
} else {
System.out.println("Forcing shutdown...");
executor.shutdownNow();
}
It is generally a bad idea to terminate a running thread from the outside, because you don't know the state the thread is currently in. It's possible that it needs to do some cleanups, and it won't be able to do that when you forcefully shut it down. That's why all methods of Thread which do that are marked as deprecated.
It's much better to use one of the many techniques which are available for interprocess communication to signal the procedure running in the thread itself that it has to abort its work and exit normally. One way to do this is to add an abort() method to your runnable, which raises a flag declared as volatile. The inner loop of your Runnable checks that flag and exits (in a controlled fashion) when that flag is raised.
I have a Runnable thread which loops through an infinite loop. Per iteration it sleeps upto next task time and then does some task. This task is very critical hence makes the thread running it also very critical. I am not really a java thread expert so I was wondering what can be the various scenarios or possibilities where the JVM may decide to stop / terminate this thread. At the application level there is no restriction for number of running threads or so. I am concerned about how JVM would behave for a long-run.
For now everything works fine in my local test system but I could hardly test this for some hours. This is an web application running under Apache Tomcat.
The thread creation and running is simple as shown below :
Thread taskThread = new Thread(new TaskRunnable(taskObject));
taskThread.start();
Loop :
public void run()
{
for (;;)
{
long sleepTime = this.taskObject.getNextTaskTime() - System.currentTimeMillis();
if (sleepTime > 0L) {
try
{
Thread.sleep(sleepTime);
}
catch (InterruptedException localInterruptedException)
{
localInterruptedException.printStackTrace();
}
}
this.taskObject.performTask(); // also computes next task time
}
}
Or this will work fine for a long-run as long as there are no exceptions in the running thread itself..
Java does not terminate threads on it's own unless one of three things happen:
The JVM is shut down
The thread's (or it's Runnable's) run() method exits
An uncaught exception is thrown from it's (or it's Runnable's) run() method.
This thread will stay up as long as the JVM is up or it is interrupted:
public class MyLongRunningThread extends Thread {
#Override
public void run() {
while(true) {
try {
// Do stuff
} catch(InterruptedException e) {
// The thread was interrupted, which means someone wants us to stop
System.out.println("Interrupted; exiting");
return;
} catch(RuntimeException e) {
e.printStackTrace();
}
}
}
}
Note that the only way the thread will be interrupted is if you (or some framework you're using) calls it's interrupt() method.
I am working on multi threading and i got a question regard thread sleep method. when i execute sleep()(with time t1) method on already in sleeping thread(with time t2). The total sleep time is t1+t2 or t2(if t2 > t1) or t1 (if t1 > t2):
code:
my thread class:
public class SampleThread extends Thread
{
public SampleThread(String msg)
{
super(msg);
start();
}
public void run()
{
try
{
SampleThread.sleep(1000);
System.out.
println("slept for run");
}
catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.
println("extends Thread Class is exited");
}
}
my main method :
public class TestThreads {
public static void main(String[] args) {
SampleThread st = new SampleThread("Extends Thread");
some(st);
System.out.println("main thread Executed");
}
public static void some(SampleThread t2 ){
try {
t2.sleep(10000);
System.out.println("slept for some" );
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
result:
slept for run
extends Thread Class is exited
slept for some
main thread Executed
from the result i can say that because sleep time for t2.sleep(10000) is more than SampleThread.sleep(1000) run() method exited first than main method.
But my question is how much time.
Sleep is called by currently running thread, it is not called on the thread object. So your sleep inside run methods pause the Sample thread, the one in the some method pauses your main thread (the one that started the program). Two different execution processes.
The sleep method is actually a static method of the Thread (and you are even calling it as such), which should already indicate for you, that it is not 'bound' to the thread object.
You cannot call sleep twice in the same thread, as to call it has to be awaked. There is no issue of additivity or priority.
So in your code, the second thread starts, executes its run method and pause for shorter time. In the meantime, the main thread continues and pauses for a long time, while the main thread sleeps the created thread finishes its sleeping and then terminates.
You have two different threads and neither blocks each other. So the one thread will wait for 10 seconds, and the other waits for 1 second. The total time you waited depends on which thread you cared about.
Your main waited 10 seconds, it doens't care if the other thread waits for 1 second or a million seconds (if the second thread is set as a daemon thread so it doesn't block the current app).
If your main app spins up a thread that is a daemon, it won't exit until all non-daemon threads are complete. In which case your main app will do its work, and then at the very last line it'll wait until those threads are done.
You can't execute sleep on a sleeping thread because sleep is a static method and can only cause the current thread to sleep.
t2.sleep(10000); causes the main thread to sleep, not t2. It's the same as Thread.sleep(10000).
Driver.java
public class Driver {
static Object obj = new Object();
public static void main(String [] args) throws InterruptedException
{
Thread thr = new Thread(new Runnable(){
#Override
public void run() {
System.out.println("Thread 1: Waiting for available slot.");
synchronized(obj){
try {
obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread 1: Found slot!");
long x = 0;
while(x < Integer.MAX_VALUE) x++;
System.out.println("Thread 1: Completed processing.");
System.out.println("Thread 1: Notifying other waiting threads.");
obj.notify();
}
}
});
Thread thr2 = new Thread(new Runnable(){
#Override
public void run() {
System.out.println("Thread 2: Waiting for available slot.");
synchronized(obj){
try {
obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread 2: Found slot!");
long x = 0;
while(x < Integer.MAX_VALUE) x++;
System.out.println("Thread 2: Completed processing.");
System.out.println("Thread 2: Notifying other waiting threads.");
obj.notify();
}
}
});
thr.start();
thr2.start();
System.out.println("Main Thread: All processing units busy.");
// Thread.sleep(2000); // Enable this and disable the other Thread.sleep(...) and NOW we are good. But again, 'why?' is the question.
synchronized(obj){
Thread.sleep(2000); // This causes a failure. Move it outside the synchronized and it will work why?
System.out.println("Main Thread: Found ONLY 1 available slot.");
obj.notify();
obj.wait(); // JVM should catch this as the last request so it has the least priority.
System.out.println("Main Thread: Finished and exiting...");
}
}
}
The code above will not notify the Threads because of the following line:
Thread.sleep(2000); // This causes a failure. Move it outside the synchronized and it will work why?
Please take a look at this line in context with the whole class. I am having hard time pinpointing to the reason why this simple proof-of-concept would fail if that line is placed inside ther synchronized block in the Main Thread.
Thank you
The problem is not the sleep but rather that the main thread almost always acquires the lock before one (and occasionally both) of the created threads does. If you print just inside the synchronized blocks it's much more clear what is going on:
synchronized(obj) {
System.out.println("this thread acquired the lock");
You'll see the output is almost always Thread #1, then the main thread, and finally Thread #2 after Thread #1 completes (but main has already returned).
If you run it enough times sometimes both child threads do acquire the lock first and it completes.
The reason moving the sleep to outside the synchronized block in the main thread works is it allows both child threads to reach their respective wait statements.
Read the doc.
Wakes up a single thread that is waiting on this object's
monitor.
If it is sleeping then it is not waiting.
There is other related problem, it is not possible to reach the notify line while the other thread is in the sleep as it keeps the monitor (lock) and the other thread can't run inside the synchronized block. This is always that way as both wait and notify must be run inside related syncrhonized blocks (against the same monitor).
sleep holds the lock, but wait doesn't. so when your main thread is sleeping, both thr and thr2 can't get the lock until main thread notifies them. At that moment, they start to wait and can't receive any notify()
The problem is that sleep does not release the monitor, that is: while the main thread is sleeping, all the other threads cannot enter the synchronized block, so they are basically sleeping with the main thread.
The moment the main thread wakes up, it does notify, but since no one yet entered the wait() position, no one is listening. Then the main thread waits and therefore releases the monitor, so now all threads can proceed to the wait() state, but no one is left to wake them up. -> Deadlock
Please help me find the reason for Thread leak in the code below. The TestThread does not get garbage collected even after run() has completed (verified from the consoled print statement) and the main method has exited (verified from print statement and profiler tool).
The TestThread, however, gets garbage collected if it is set as a Daemon Thread i.e. t.setDaemon(true). The code below is just a sample code which illustrates the problem in my application. I'm trying to use some pre-existing scheduling class (which was designed by someone else using ScheduledExecutorService). I notice that when I keep scheduling multiple Runnables with the class, the created threads never get garbage collected.
public class ThreadTest {
static void runThreadWithExecutor() {
final String name = "TestThread";
ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor(
new ThreadFactory() {
#Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r, name);
t.setDaemon(false);
return t;
}
});
ses.schedule(new Runnable() {
#Override
public void run() {
System.out.println("entered " + name);
System.out.println("exiting " + name);
}},
2,
TimeUnit.SECONDS);
}
public static void main(String[] args) throws InterruptedException {
System.out.println("entered main");
runThreadWithExecutor();
Thread.sleep(5000);
System.out.println("exiting main");
}
}
This is due to the fact that you are not calling shutdown() on your executor service after you have scheduled your last job:
ses.schedule(...);
// this stops any management threads but existing jobs will still run
ses.shutdown();
I just added the shutdown() call to your code and it exits fine. This is true of all ExecutorServices. Without the shutdown the thread pool continues to wait for more jobs to be submitted and is never GC'd.
See #John's answer below for more details.
#Gray is correct with his assessment I just figure I add the why he is correct. The ExecutorService is a thread-pool which will reuse the threads.
Unlike new Thread(runnable).start(); when the run method completes the thread completes and will then be GC'd. When an Executor Runnable completes the thread will sit there and wait for another runnable task to be submitted and used. So by shutting down you are telling the executor to end all of the Threads in the thread pool.
To answer your last part. Setting it to daemon works only because there are no other (non-daemon) threads running. If your application started some other non daemon thread the Executor thread's will continue. Remember a daemon thread will be killed when only daemon threads are running.