Java Notes
Complete guide to Daemon Threads in Java — what they are, how they differ from user threads, JVM shutdown behavior, practical use cases like GC and auto-save, and common pitfalls.
What is a Daemon Thread?
A daemon thread is a low-priority background thread that provides services to user threads. The key characteristic: the JVM exits when only daemon threads remain alive.
Think of daemon threads as background services:
- They support the main work (user threads)
- They don't prevent the program from exiting
- They're abruptly terminated when the JVM shuts down
User Threads vs Daemon Threads
| Feature | User Thread | Daemon Thread |
|---|---|---|
| JVM waits for it? | YES | NO |
| Purpose | Main application work | Background services |
| Shutdown | Runs to completion | Abruptly killed |
| Default | All new threads | Must explicitly set |
| Examples | main, workers | GC, auto-save, logging |
Creating Daemon Threads
Try it in WoHoCode
Edit the program, then run it here.
Run this example to see its output.
Output:
| isDaemon | true |
| Main thread is daemon | false |
| [Daemon] Background tick | 1 |
| [Daemon] Background tick | 2 |
| [Daemon] Background tick | 3 |
| [Daemon] Background tick | 4 |
Notice: The daemon was in an infinite loop, but the program still exits when main finishes!
Daemon vs Non-Daemon Comparison
Try it in WoHoCode
Edit the program, then run it here.
Run this example to see its output.
Output:
The daemon only got to step 4-5 before the JVM shut down (after user thread finished).
Real-World Use Case: Auto-Save Service
Try it in WoHoCode
Edit the program, then run it here.
Run this example to see its output.
Output:
| [Edit] Added | "Hello World" (v1) |
| [Edit] Added | "Adding second paragraph" (v2) |
| [Edit] Added | "Fixing typos" (v3) |
| [Edit] Added | "Final changes" (v4) |
Real-World Use Case: Heartbeat Monitor
Try it in WoHoCode
Edit the program, then run it here.
Run this example to see its output.
Important Rules and Pitfalls
Try it in WoHoCode
Edit the program, then run it here.
Run this example to see its output.
Common Mistakes
1. Setting daemon after start()
Thread t = new Thread(() -> {});
t.start();
t.setDaemon(true); // ❌ IllegalThreadStateException!2. Doing critical work in daemon threads
// ❌ BAD: File write might be cut short!
Thread saver = new Thread(() -> {
// This might never complete — daemon can be killed anytime!
writeToFile(importantData);
});
saver.setDaemon(true);
saver.start();3. Assuming finally blocks execute in daemon threads
Thread daemon = new Thread(() -> {
try {
while (true) { Thread.sleep(100); }
} finally {
// ❌ This may NEVER execute!
releaseResources();
}
});
daemon.setDaemon(true);Interview Questions
Q1: What is a daemon thread?
Answer: A daemon thread is a background service thread that doesn't prevent the JVM from exiting. When all user (non-daemon) threads finish, the JVM terminates and all daemon threads are killed immediately. Examples: Garbage Collector, Finalizer thread.
Q2: How do you create a daemon thread?
Answer: Call thread.setDaemon(true) BEFORE calling thread.start(). Setting it after start throws IllegalThreadStateException.
Q3: What happens to daemon threads when the JVM shuts down?
Answer: They are immediately and abruptly terminated. No finally blocks are guaranteed to run, no shutdown hooks are called for them specifically. Any I/O operation in progress may be left incomplete.
Q4: Can the main thread be a daemon thread?
Answer: No. The main thread is always a user (non-daemon) thread. You cannot call setDaemon(true) on it because it's already started.
Q5: Do child threads inherit the daemon status of their parent?
Answer: Yes. A thread created by a daemon thread is also a daemon. A thread created by a user thread is also a user thread. You can override this by calling setDaemon() before start().
Q6: When should you use daemon threads?
Answer: For background services that support the main application but shouldn't keep it alive: auto-save, heartbeat monitoring, cache cleanup, garbage collection, log flushing, session timeout checking. Never for critical data writes or transactions.
Q8: What happens to daemon thread's finally block when JVM shuts down?
A: It does NOT execute! When all user threads finish, the JVM exits immediately, killing all daemon threads without running their finally blocks. This is a critical difference — never put important cleanup (file saves, database commits) in daemon threads because there's no guarantee they'll complete.
Q9: Can you change a thread's daemon status after it has started?
A: No. Calling setDaemon() after start() throws IllegalThreadStateException. Daemon status must be set before the thread starts. Once running, a thread's daemon/user classification is fixed for its lifetime.
Q10: What are real-world examples of daemon threads in Java?
A: (1) Garbage Collector — reclaims memory in background. (2) Signal dispatcher thread. (3) Finalizer thread. (4) JMX monitoring threads. (5) Timer threads for housekeeping. In applications: (6) Log flushing, (7) Cache cleanup, (8) Heartbeat/health-check threads, (9) Auto-save background threads.
Q11: Do child threads inherit daemon status from parent?
A: Yes! A new thread inherits the daemon status of the thread that creates it. If a daemon thread creates a child thread, that child is also a daemon by default. If a user thread creates a child, it's a user thread. Override with setDaemon() before start().
Q12: What is the relationship between daemon threads and thread pools?
A: By default, ExecutorService creates user threads (preventing JVM shutdown). To create daemon thread pools, provide a custom ThreadFactory: Executors.newFixedThreadPool(4, r -> { Thread t = new Thread(r); t.setDaemon(true); return t; }). Use daemon pools for non-critical background tasks.
Continue the lesson path