Understanding User Threads and Daemon Threads in Java
This article explains the differences between user threads and daemon (background) threads in Java, demonstrates how to identify, create, and configure them—including thread pools—and discusses important considerations, priority effects, and typical use cases such as garbage collection.
In Java, threads are divided into two categories: user (non‑daemon) threads and daemon (background) threads, a distinction that is often overlooked. By default, both the main thread and any newly created thread are user threads, which can be verified using the isDaemon() method.
Identifying thread type : calling Thread.currentThread().isDaemon() returns false for user threads. Example code demonstrates this check.
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("我是子线程");
}
});
System.out.println("子线程==守护线程:" + thread.isDaemon());
System.out.println("主线程==守护线程:" + Thread.currentThread().isDaemon());
}The output shows that both the main thread and the newly created thread are user threads.
Converting a thread to a daemon : Use setDaemon(true) before start() to turn a user thread into a daemon thread. For thread pools, a custom ThreadFactory must set each worker thread as daemon.
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("我是子线程");
}
});
// Set as daemon
thread.setDaemon(true);
System.out.println("子线程==守护线程:" + thread.isDaemon());
System.out.println("主线程==守护线程:" + Thread.currentThread().isDaemon());
}For a thread pool:
ExecutorService threadPool = Executors.newFixedThreadPool(10, new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
// Set thread as daemon
t.setDaemon(true);
return t;
}
});Daemon vs. User thread behavior : A daemon thread runs in the background and terminates automatically when all user threads finish. Demonstrations show that a daemon thread may not complete its work unless the main thread waits (e.g., using join() ).
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 1; i <= 10; i++) {
System.out.println("i:" + i);
try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); }
}
}
});
thread.setDaemon(true);
thread.start();
thread.join(); // Wait for daemon thread to finish
System.out.println("子线程==守护线程:" + thread.isDaemon());
System.out.println("主线程==守护线程:" + Thread.currentThread().isDaemon());
}When join() is used, the program waits for the daemon thread to finish before exiting.
Important considerations :
Calling setDaemon(true) must occur before start() ; otherwise an IllegalThreadStateException is thrown and the daemon flag is ignored.
Threads created inside a daemon thread inherit the daemon status by default.
The join() method forces the JVM to wait for a daemon thread, contrary to the usual automatic termination.
Priority : Thread type (daemon vs. user) does not affect scheduling priority. Changing a thread’s priority (e.g., setPriority(Thread.MAX_PRIORITY) ) influences execution order regardless of daemon status.
Typical use cases : Daemon threads are ideal for non‑essential background services such as garbage collection or health‑check monitors that should not prevent the JVM from shutting down once all user threads complete.
Summary : Daemon threads serve user threads and terminate automatically when no user threads remain. They have lower business‑logic importance but the same scheduling priority as user threads. Common scenarios include garbage collection and auxiliary server tasks, and child threads of a daemon inherit the daemon flag.
Full-Stack Internet Architecture
Introducing full-stack Internet architecture technologies centered on Java
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.