Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

finally block in daemon thread

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.

like image 704
Fedor Skrynnikov Avatar asked Jul 18 '11 12:07

Fedor Skrynnikov


People also ask

Does finally {} block always run?

A finally block always executes, regardless of whether an exception is thrown. The following code example uses a try / catch block to catch an ArgumentOutOfRangeException.

Does daemon thread end before main thread?

Properties of Java Daemon ThreadJVM terminates itself when all user threads finish their execution. If JVM finds a running daemon thread, it terminates the thread and, after that, shutdown it. JVM does not care whether the Daemon thread is running or not. It is an utmost low priority thread.

In which situation finally block will not executed?

Note: The finally block may not execute if the JVM exits while the try or catch code is being executed.

In which scenario finally block is executed?

A finally block is always get executed whether the exception has occurred or not. If an exception occurs like closing a file or DB connection, then the finally block is used to clean up the code. We cannot say the finally block is always executes because sometimes if any statement like System.


2 Answers

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.

like image 137
Joachim Sauer Avatar answered Oct 31 '22 10:10

Joachim Sauer


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
like image 44
Mike Avatar answered Oct 31 '22 12:10

Mike