Daemon Threads in Java
A daemon thread in Java is a background helper thread that does not keep the program running. The JVM exits as soon as all user (non-daemon) threads have finished, even if daemon threads are still working; those daemon threads are simply stopped. The garbage collector is an example of a daemon thread. You make a thread a daemon with setDaemon(true) before starting it. In this lesson, you will learn how daemon threads behave and when to use them.
User Threads vs Daemon Threads
| User thread | Daemon thread | |
|---|---|---|
| Keeps the JVM alive | Yes | No |
Default for new Thread | Inherited; main is a user thread | Only if created by a daemon thread |
| When the JVM exits | Waits for it | Stopped abruptly, without finally blocks running |
| Typical use | Real work | Background services: cleanup, monitoring, caches |
Methods
| Method | Description |
|---|---|
setDaemon(boolean on) | It is used to mark a thread as daemon; must be called before start(). |
isDaemon() | It returns true for a daemon thread. |
Example: The JVM Doesn't Wait for Daemons
Let's see an example where a daemon thread would print forever, but the program still ends.
public class DaemonDemo {
public static void main(String[] args) throws InterruptedException {
Thread heartbeat = new Thread(() -> {
int beat = 1;
while (true) {
System.out.println("heartbeat " + beat++);
try {
Thread.sleep(200);
} catch (InterruptedException e) {
return;
}
}
});
heartbeat.setDaemon(true);
System.out.println("Is daemon? " + heartbeat.isDaemon());
heartbeat.start();
Thread.sleep(500);
System.out.println("Main ends now");
}
}Is daemon? true
heartbeat 1
heartbeat 2
heartbeat 3
Main ends nowExplanation: The heartbeat thread has an endless loop. Because it is a daemon, the JVM doesn't wait for it: when main, the last user thread, finishes, the program exits and the heartbeat stops. Without setDaemon(true), the program would never end.
Example: setDaemon After start()
public class TooLate {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(() -> { });
t.start();
try {
t.setDaemon(true);
} catch (IllegalThreadStateException e) {
System.out.println("setDaemon after start: "
+ e.getClass().getSimpleName());
}
t.join();
}
}setDaemon after start: IllegalThreadStateExceptionExplanation: A thread's daemon status is fixed once it starts. Calling setDaemon afterwards throws IllegalThreadStateException.
Common Mistakes
Calling setDaemon after start(). It throws.
Using a daemon thread to save data. It may be killed before finishing.
Wondering why a program never exits. A forgotten non-daemon background thread is keeping it alive.
Interview Corner
What is a daemon thread?
A daemon thread is a low-priority background service thread that doesn't prevent the JVM from exiting: the JVM shuts down when all non-daemon (user) threads have finished, abruptly stopping any daemon threads without running their finally blocks. A thread is marked as daemon with setDaemon(true) before start(), and new threads inherit the daemon status of their creator. The garbage collector is a typical example.
Practice
- Easy: Change
heartbeatto a normal thread and observe that the program never ends (stop it with Ctrl+C). - Harder: Create a daemon thread that prints memory usage every second while the main thread does three seconds of work.
Key Takeaways
Was this tutorial helpful?