Thread Scheduling and Daemon Threads
Understand how threads get opportunities to execute and how Java uses daemon threads for background activities.
1. What Is Thread Scheduling?
Imagine you are working on a computer with multiple applications open.
You might be listening to music, downloading a file, and writing a document at the same time.
Your computer manages these activities and gives them opportunities to use the processor.
Something similar happens when multiple threads are running in a Java application.
The process of deciding which thread gets an opportunity to execute is called thread scheduling.
Java uses the underlying operating system and JVM implementation to manage thread execution.
2. Does Java Execute Threads in a Fixed Order?
No. This is one of the most important things to understand about multithreading.
Let's create two threads.
public class SchedulingExample {
public static void main(String[] args) {
Thread thread1 = new Thread(() -> {
System.out.println("Thread 1 is running");
});
Thread thread2 = new Thread(() -> {
System.out.println("Thread 2 is running");
});
thread1.start();
thread2.start();
}
}
You might expect the output to always be:
Thread 1 is running
Thread 2 is running
But that order is not guaranteed.
You might also see:
Thread 2 is running
Thread 1 is running
Why?
Because both threads are given an opportunity to execute independently. Their exact execution order depends on thread scheduling.
Remember: Calling start()
on one thread before another does not guarantee that
the first thread will finish its work first.
3. What Is Thread Priority?
Java allows us to assign a priority to a thread.
A priority is a value that can be used by the thread scheduling mechanism when deciding which thread should get an opportunity to execute.
Java provides priorities from 1 to 10.
- 1: Minimum priority
- 5: Normal priority (default)
- 10: Maximum priority
Java provides constants for these values:
Thread.MIN_PRIORITY
Thread.NORM_PRIORITY
Thread.MAX_PRIORITY
Let's see how to assign a priority.
Thread worker = new Thread(() -> {
System.out.println("Worker is running");
});
worker.setPriority(Thread.MAX_PRIORITY);
worker.start();
We can also check a thread's priority using
getPriority().
int priority = worker.getPriority();
One important thing to remember:
A higher priority does not guarantee that a thread will execute first.
Thread priority is only a scheduling hint. The exact scheduling behaviour depends on the JVM and operating system.
4. What Are Daemon Threads?
Now let's understand another important concept.
Imagine a Java application that performs some important work for a user.
Along with this work, the application may also perform background activities, such as periodically checking something or maintaining supporting information.
These background activities should not necessarily keep the entire application running after its main work has finished.
Java provides a special type of thread for such background activities. It is called a daemon thread.
A daemon thread is a background thread that supports the execution of an application.
Examples of activities that can be handled by daemon threads include background monitoring and periodic maintenance tasks.
5. User Threads vs Daemon Threads
Java threads are commonly discussed in two categories:
- User Threads: Regular threads that perform the application's main work.
- Daemon Threads: Background threads that support the application.
The important difference is how they affect the application's lifetime.
The JVM normally continues running while at least one user thread is still alive.
When all user threads have finished, the JVM can exit even if daemon threads are still running.
In simple words:
Daemon threads do not keep the JVM alive.
6. How to Create a Daemon Thread
Java provides the setDaemon() method
to mark a thread as a daemon thread.
Let's see a simple example.
public class DaemonExample {
public static void main(String[] args) {
Thread backgroundThread = new Thread(() -> {
while (true) {
System.out.println("Background thread is running");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("Background thread interrupted");
return;
}
}
});
backgroundThread.setDaemon(true);
backgroundThread.start();
System.out.println("Main thread has finished");
}
}
Let's understand this example.
- We create a thread that continuously performs a background activity.
- We call
setDaemon(true)to mark it as a daemon thread. - We start the thread.
- The main thread prints its message and finishes.
- Once no user threads remain, the JVM can exit, even though the daemon thread is still running.
You may see the background thread print its message several times before the application exits.
The exact number of messages is not guaranteed because thread execution is not predictable.
7. An Important Rule About setDaemon()
There is one important rule:
We must call setDaemon() before starting the thread.
For example, this is correct:
Thread worker = new Thread(() -> {
System.out.println("Working...");
});
worker.setDaemon(true);
worker.start();
But this is incorrect:
Thread worker = new Thread(() -> {
System.out.println("Working...");
});
worker.start();
worker.setDaemon(true);
Calling setDaemon() after the thread has
started throws IllegalThreadStateException.
We can also check whether a thread is a daemon thread
using isDaemon().
boolean daemon = worker.isDaemon();
8. What Did We Learn?
- Thread scheduling decides which threads get opportunities to execute.
- Java does not guarantee a fixed execution order for multiple threads.
- Thread priorities range from 1 to 10.
- A higher priority does not guarantee earlier execution.
- Daemon threads perform background activities.
- The JVM can exit when all user threads have finished, even if daemon threads remain.
- We must call
setDaemon(true)before starting a thread.
Remember: Thread scheduling controls execution opportunities, while daemon threads support background activities without keeping the JVM alive.
Test Your Understanding
Let's check what you have learned in this class.
1. What is thread scheduling?
2. Does a higher thread priority guarantee that a thread will execute first?
3. What is a daemon thread?
4. When should we call setDaemon(true)?
5. What happens when all user threads finish but daemon threads are still running?
Class Summary
Let's quickly revise the two concepts we learned today.
- Thread scheduling determines which threads get opportunities to execute.
- Java does not guarantee a fixed execution order.
- Thread priorities range from 1 to 10, but higher priority does not guarantee earlier execution.
- Daemon threads are used for background activities.
- The JVM can exit when all user threads have finished, even if daemon threads are still running.
- Use
setDaemon(true)before callingstart().
With this, we have completed our second part: Working with Threads!
You have completed 10 out of 46 classes.