Thread Scheduler in Java
The thread scheduler is the part of the system that decides which thread runs on a CPU core, and for how long. In modern Java, platform threads are ordinary operating-system threads, so the scheduling is done by the operating system, not by the JVM. Because of this, the order in which threads run is not guaranteed and can change from one run to the next. In this lesson, you will learn how scheduling works, what you can and can't control, and why correct programs never depend on timing.
How Scheduling Works
- Time slicing: each runnable thread gets a short slice of CPU time, then another thread gets a turn.
- Preemption: the scheduler can pause a running thread at almost any moment to run another.
- Multiple cores: with several cores, several threads truly run at the same time.
- Waiting threads are skipped: threads that are sleeping, waiting or blocked aren't given CPU time.
What You Can and Can't Control
| You can | You can't |
|---|---|
Decide when a thread starts (start()) | Decide the exact order threads run in |
Make a thread wait (sleep, join, wait) | Guarantee how long a time slice lasts |
Hint at importance (setPriority) | Rely on priorities being honored |
Coordinate threads (locks, join, queues) | Predict output order without coordination |
Example: Unpredictable Order
Let's see an example where three threads print with no coordination. Run it several times; the order may differ, so the output shown is one sample.
public class NoOrder {
public static void main(String[] args) throws InterruptedException {
Thread[] threads = new Thread[3];
String[] names = {"Navika", "Srihitha", "Advitha"};
for (int i = 0; i < 3; i++) {
String name = names[i];
threads[i] = new Thread(() -> {
for (int k = 1; k <= 2; k++) {
System.out.println(name + " " + k);
}
});
}
for (Thread t : threads) {
t.start();
}
for (Thread t : threads) {
t.join();
}
}
}Srihitha 1
Srihitha 2
Navika 1
Advitha 1
Navika 2
Advitha 2Explanation: The threads were started in the order Navika, Srihitha, Advitha, but in this run Srihitha went first, and the scheduler switched between Navika and Advitha mid-loop. Six runs on the same machine gave five different orders. Each thread's own lines stay in order (1 before 2), but lines from different threads can mix in any way.
Testing Threaded Code
Common Mistakes
Using Thread.sleep to "fix" ordering. It only makes a bug rarer; use join, locks or queues.
Assuming higher priority threads always run first. The operating system may ignore priorities.
Expecting the same output on every run. Thread interleaving changes between runs.
Practice
- Easy: Run
NoOrderfive times and write down how many different orders you see. - Harder: Change
NoOrderso the output is always Navika's lines, then Srihitha's, then Advitha's, without usingsleep.
Key Takeaways
Was this tutorial helpful?