Java Thread Priority Tutorial

In Java, each thread has a priority that helps the Thread Scheduler decide the order in which threads are executed. Thread priority is an integer value that ranges from 1 to 10, with the following constants defined in the Thread class:

Thread.MIN_PRIORITY = 1 (Lowest priority)
Thread.NORM_PRIORITY = 5 (Default priority)
Thread.MAX_PRIORITY = 10 (Highest priority)

Threads with higher priority are more likely to be executed before threads with lower priority, but thread priority is only a hint to the JVM and actual execution order is platform-dependent. Therefore, thread scheduling behavior might vary across different operating systems.

In this tutorial, we will explore how to set and use thread priorities in Java with several examples.

1. Understanding Thread Priority

By default, when a thread is created, it inherits the priority of the thread that created it. The priority can be changed using the setPriority() method, and you can retrieve a thread's priority using the getPriority() method.

Syntax for Setting and Getting Thread Priority

// Set thread priority
thread.setPriority(int priority);  // Priority between 1 and 10

// Get thread priority
int priority = thread.getPriority();

2. Creating a Thread with Priority

Here’s a basic example of setting thread priority in Java.

Example:

Setting and Getting Thread Priority

public class ThreadPriorityExample {
    public static void main(String[] args) {
        // Creating a thread with normal priority
        Thread thread1 = new Thread(() -> {
            System.out.println("Thread 1 Priority: " + Thread.currentThread().getPriority());
        });

        // Creating a thread with maximum priority
        Thread thread2 = new Thread(() -> {
            System.out.println("Thread 2 Priority: " + Thread.currentThread().getPriority());
        });

        // Setting priorities
        thread1.setPriority(Thread.NORM_PRIORITY); // 5 (Normal priority)
        thread2.setPriority(Thread.MAX_PRIORITY);  // 10 (Maximum priority)

        // Start both threads
        thread1.start();
        thread2.start();
    }
}

Explanation:

thread1 is set to normal priority (5), and thread2 is set to maximum priority (10).
getPriority() returns the priority of each thread, which is printed to the console.

Output:

Thread 1 Priority: 5
Thread 2 Priority: 10

3. Thread Priority with Multiple Threads

In this example, we create multiple threads with different priorities and observe the execution order.

Example:

Running Threads with Different Priorities

public class MultiThreadPriorityExample {
    public static void main(String[] args) {
        // Creating thread 1 (Low Priority)
        Thread thread1 = new Thread(() -> {
            for (int i = 1; i <= 5; i++) { System.out.println("Low Priority Thread (1): " + i); } }); // Creating thread 2 (Normal Priority) Thread thread2 = new Thread(() -> {
            for (int i = 1; i <= 5; i++) { System.out.println("Normal Priority Thread (5): " + i); } }); // Creating thread 3 (High Priority) Thread thread3 = new Thread(() -> {
            for (int i = 1; i <= 5; i++) {
                System.out.println("High Priority Thread (10): " + i);
            }
        });

        // Setting thread priorities
        thread1.setPriority(Thread.MIN_PRIORITY);  // 1
        thread2.setPriority(Thread.NORM_PRIORITY); // 5
        thread3.setPriority(Thread.MAX_PRIORITY);  // 10

        // Start all threads
        thread1.start();
        thread2.start();
        thread3.start();
    }
}

Explanation:

Thread 1 has the lowest priority (Thread.MIN_PRIORITY = 1).
Thread 2 has the default priority (Thread.NORM_PRIORITY = 5).
Thread 3 has the highest priority (Thread.MAX_PRIORITY = 10).
The order in which the threads are executed may differ depending on the underlying operating system and JVM implementation.

Sample Output (may vary):

High Priority Thread (10): 1
High Priority Thread (10): 2
High Priority Thread (10): 3
High Priority Thread (10): 4
High Priority Thread (10): 5
Normal Priority Thread (5): 1
Normal Priority Thread (5): 2
Normal Priority Thread (5): 3
Normal Priority Thread (5): 4
Normal Priority Thread (5): 5
Low Priority Thread (1): 1
Low Priority Thread (1): 2
Low Priority Thread (1): 3
Low Priority Thread (1): 4
Low Priority Thread (1): 5

Note: Higher-priority threads (thread3) are more likely to run first, but this is not guaranteed since thread scheduling depends on the JVM and operating system.

4. Effect of Thread Priority in Multithreaded Programs

Thread priorities can influence the thread scheduling, but priorities are platform-dependent and do not guarantee strict control over the thread execution order. In this example, we create more threads and observe how priorities might affect the execution.

Example:

Thread Priority with Multiple Threads Running Simultaneously

public class ComplexThreadPriorityExample {
    public static void main(String[] args) {
        // Creating 5 threads with different priorities
        for (int i = 1; i <= 5; i++) { final int threadNumber = i; Thread thread = new Thread(() -> {
                for (int j = 1; j <= 3; j++) {
                    System.out.println("Thread " + threadNumber + " is running. Iteration: " + j);
                }
            });

            // Set thread priority based on threadNumber
            if (threadNumber == 1) {
                thread.setPriority(Thread.MIN_PRIORITY); // Lowest priority
            } else if (threadNumber == 5) {
                thread.setPriority(Thread.MAX_PRIORITY); // Highest priority
            } else {
                thread.setPriority(Thread.NORM_PRIORITY); // Normal priority
            }

            // Start the thread
            thread.start();
        }
    }
}

Explanation:

We create 5 threads, each with different priorities: thread 1 gets the lowest priority, thread 5 gets the highest priority, and the others get normal priority.
Output can vary based on the platform and JVM, but higher-priority threads are more likely to run first.

Sample Output (may vary):

Thread 5 is running. Iteration: 1
Thread 5 is running. Iteration: 2
Thread 5 is running. Iteration: 3
Thread 2 is running. Iteration: 1
Thread 2 is running. Iteration: 2
Thread 2 is running. Iteration: 3
Thread 3 is running. Iteration: 1
Thread 3 is running. Iteration: 2
Thread 3 is running. Iteration: 3
Thread 4 is running. Iteration: 1
Thread 4 is running. Iteration: 2
Thread 4 is running. Iteration: 3
Thread 1 is running. Iteration: 1
Thread 1 is running. Iteration: 2
Thread 1 is running. Iteration: 3

5. Limitations of Thread Priority

While thread priority can influence the order in which threads are executed, it is important to understand its limitations:

Platform-Dependent: Thread priorities are only hints to the JVM. Different operating systems may handle thread priorities differently, so behavior may vary across platforms.
No Strict Guarantees: Even with different priorities, the execution order of threads is not guaranteed. Other factors, such as the number of available CPUs and system load, can affect thread scheduling.
Too Many High-Priority Threads: If too many threads have the highest priority, it can lead to starvation of lower-priority threads.

Example:

Overloading the Scheduler with High-Priority Threads

public class StarvationExample {
    public static void main(String[] args) {
        // High-priority threads
        for (int i = 1; i <= 3; i++) { Thread highPriorityThread = new Thread(() -> {
                for (int j = 1; j <= 5; j++) { System.out.println(Thread.currentThread().getName() + " (High Priority) is running."); } }); highPriorityThread.setPriority(Thread.MAX_PRIORITY); highPriorityThread.setName("High-Priority Thread " + i); highPriorityThread.start(); } // Low-priority thread Thread lowPriorityThread = new Thread(() -> {
            for (int j = 1; j <= 5; j++) {
                System.out.println(Thread.currentThread().getName() + " (Low Priority) is running.");
            }
        });
        lowPriorityThread.setPriority(Thread.MIN_PRIORITY);
        lowPriorityThread.setName("Low-Priority Thread");
        lowPriorityThread.start();
    }
}

Explanation:

Three high-priority threads are created alongside one low-priority thread.
The low-priority thread might not get enough CPU time due to the dominance of high-priority threads, leading to thread starvation.

Sample Output (may vary):

High-Priority Thread 1 (High Priority) is running.
High-Priority Thread 2 (High Priority) is running.
High-Priority Thread 3 (High Priority) is running.
...
(Low-priority thread may get very little or no CPU time, depending on the system load and JVM)

6. Best Practices with Thread Priority

Use Default Priority When Possible: Unless necessary, stick to the default priority (NORM_PRIORITY = 5) to avoid unexpected behavior across different systems.
Avoid Overusing High Priority: Overloading the scheduler with many high-priority threads can cause lower-priority threads to starve, resulting in poor performance and responsiveness.
Test on Different Platforms: Since thread scheduling behavior can vary between platforms, test your multithreaded application on different operating systems to ensure consistent behavior.
Handle Concurrency Properly: Use proper synchronization mechanisms (such as wait(), notify(), and notifyAll() or Lock objects) instead of relying solely on thread priority to manage execution order.

Conclusion

Thread priority in Java gives you a way to suggest the relative importance of different threads to the JVM's thread scheduler. However, thread priority does not guarantee strict control over thread execution order, and it is heavily dependent on the underlying operating system.

In this tutorial, we covered:

How to set and get thread priority.
How thread priority can influence the order of execution in multithreaded programs.
The limitations of thread priority and how it can lead to issues like thread starvation.
Best practices when using thread priority to ensure reliable and maintainable multithreaded applications.

By understanding thread priority and the underlying system behavior, you can write more efficient and responsive multithreaded applications in Java.

Related posts

Java Lambda Expressions

Java Base64 encoding and decoding

Java Regular Expressions tutorial with Examples