What is daemon thread?
In Java, threads are broadly categorized into two types: user threads (also known as non-daemon threads) and daemon threads. Daemon threads are background service threads that do not prevent the Java Virtual Machine (JVM) from exiting when all user threads have completed their execution.
What is a Daemon Thread?
A daemon thread is a low-priority thread that performs background tasks or services for other threads. Its primary characteristic is that it does not prevent the Java Virtual Machine (JVM) from terminating. If the only threads running in a JVM are daemon threads, the JVM exits.
Key Characteristics of Daemon Threads
- Background Services: They are typically used for background tasks like garbage collection, finalization, or monitoring, providing support to user threads.
- JVM Exit Behavior: The JVM will exit if only daemon threads remain. It does not wait for daemon threads to complete their execution.
- Abrupt Termination: When the JVM shuts down, daemon threads are terminated abruptly. They do not get a chance to execute
finallyblocks or perform graceful cleanups. - Priority: While not strictly enforced, daemon threads are generally considered low-priority and are often used for non-critical operations.
User Threads vs. Daemon Threads
The distinction between user (non-daemon) and daemon threads is crucial for understanding JVM lifecycle management. User threads are considered vital and keep the JVM alive, whereas daemon threads are subservient and allow the JVM to exit once all user threads are gone.
| Characteristic | User (Non-Daemon) Thread | Daemon Thread |
|---|---|---|
| JVM Lifecycle | Prevents JVM from exiting | Does not prevent JVM from exiting |
| Purpose | Main application logic, critical tasks | Background services, supporting tasks |
| Termination | JVM waits for completion | JVM terminates them abruptly on exit |
| Default Status | By default, new threads are user threads | Must be explicitly set using `setDaemon(true)` |
How to Create a Daemon Thread
You can mark a thread as a daemon thread by calling the setDaemon(true) method on the Thread object before starting it. Once a thread has been started, you cannot change its daemon status.
public class DaemonThreadExample {
public static void main(String[] args) {
Thread userThread = new Thread(() -> {
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(1000);
System.out.println("User Thread running: " + i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("User Thread finished.");
});
Thread daemonThread = new Thread(() -> {
while (true) {
try {
Thread.sleep(500);
System.out.println("Daemon Thread running...");
} catch (InterruptedException e) {
System.out.println("Daemon Thread interrupted.");
break;
}
}
System.out.println("Daemon Thread finished."); // This might not be printed
});
// Set daemon status BEFORE starting the thread
daemonThread.setDaemon(true);
userThread.start();
daemonThread.start();
System.out.println("Main thread finished.");
// JVM will exit once userThread finishes, even if daemonThread is still running.
}
}
Important Considerations
- Timing of
setDaemon(): ThesetDaemon(true)method must be called *before* the thread is started (i.e., beforethread.start()). Calling it after starting the thread will result in anIllegalThreadStateException. - Resource Management: Because daemon threads are abruptly terminated, they are not suitable for tasks that require careful resource management, such as closing file streams, database connections, or releasing locks. There's no guarantee that
finallyblocks will execute. - JVM Shutdown Hooks: For critical cleanup operations that must run during JVM shutdown, regardless of thread type, use
Runtime.getRuntime().addShutdownHook(Thread hook). Shutdown hooks run before the JVM exits and after all user threads have completed. System.exit(): CallingSystem.exit()terminates the JVM immediately, regardless of whether user or daemon threads are running, effectively stopping all threads.
Common Examples of Daemon Threads in Java
- Garbage Collector (GC): The JVM's garbage collector thread is a classic example of a daemon thread. It runs in the background to reclaim memory occupied by unreferenced objects.
- Finalizer Thread: Responsible for running the
finalize()method of objects when they are garbage collected. - Attach Listener (JVM Internal): Used for tools to connect to a running JVM.