Back to Thread Lifecycle: Priority, Interruption, Factory
Q1Question 1 of 5

What is thread priority?

Key Concepts
  • Priority is an integer hint from 1 (MIN_PRIORITY) to 10 (MAX_PRIORITY), with 5 (NORM_PRIORITY) as default.
  • A new thread inherits the priority of the creating thread, not always the default of five.
  • The JLS guarantees nothing about scheduling order; priority is a suggestion, not a rule.
  • The JVM maps Java's 10 levels onto the OS model; several levels may collapse to the same OS level.
  • Linux's Completely Fair Scheduler ignores priority to prevent starvation.
  • Priority inversion and starvation are the two dangers if priority were strictly honoured.
  • Use separate thread pools, PriorityBlockingQueue, or cgroups instead of setPriority for resource control.

Definition

Thread priority is a hint, not a promise: the JLS guarantees nothing and modern schedulers mostly ignore it, so never use it for correctness.
  • Range – integers from Thread.MIN_PRIORITY (1) to Thread.MAX_PRIORITY (10), default Thread.NORM_PRIORITY (5).
  • Setting – setPriority(int) changes it; values outside 1-10 throw IllegalArgumentException.
  • Inheritance – a new thread inherits the creating thread's priority, not necessarily 5.
  • JLS guarantee – none; priority is only a suggestion to the OS scheduler.
  • OS mapping – the JVM squeezes 10 Java levels into whatever model the host OS offers; levels may collapse.
  • Modern schedulers – Linux CFS ignores the hint to ensure fairness and prevent starvation.

Imagine Rajesh walks into National Bank of India and writes "URGENT" on his token slip. The queue system was designed to be fair, so in practice Rajesh is served in roughly the same order as everybody else. His note is a polite hint, not a rule. Thread priority is exactly that note.

Understanding the Concepts

What is the priority range?

Every Java thread carries a priority field. You read it with getPriority() and change it with setPriority(int). The three constants are Thread.MIN_PRIORITY (1), Thread.NORM_PRIORITY (5), and Thread.MAX_PRIORITY (10). Passing anything outside 1-10 throws IllegalArgumentException.

JAVA
package com.bank.thread;

public class PriorityDemo {
    public static void main(String[] args) {
        Thread worker = new Thread(() -> processSettlement(), "settlement-worker");
        worker.setPriority(Thread.MAX_PRIORITY);   // 10
        System.out.println(worker.getPriority());  // 10
        worker.start();
    }

    private static void processSettlement() {
        System.out.println("Processing settlement with priority: "
            + Thread.currentThread().getPriority());
    }
}

How does priority inheritance work?

A new thread inherits the priority of the thread that created it, not always the default of 5. If your main thread has been set to priority 7 and you spawn a worker, that worker starts at 7.

JAVA
package com.bank.thread;

public class PriorityInheritanceDemo {
    public static void main(String[] args) throws InterruptedException {
        Thread.currentThread().setPriority(7);
        Thread child = new Thread(() -> {
            System.out.println("Child priority: " + Thread.currentThread().getPriority());
        });
        child.start();
        child.join();
        // prints 7, not 5: inherited from the creating thread
    }
}

How does Java priority map to the OS?

Java has 10 levels, but Linux uses nice values (-20 to +19), Windows has 7 scheduling priority levels, and macOS has another scheme. The JVM squeezes the Java range into whatever the platform offers. Several Java levels can collapse onto the same OS level. On many Linux JVMs, setting priority has no observable effect without elevated privileges (CAP_SYS_NICE).

What does the JLS guarantee?

The Java Language Specification is explicit: priority is only a hint. It does not say a higher-priority thread will be scheduled first, more often, or at all. Any application logic that depends on scheduling order based on priority is formally incorrect.

Why do modern schedulers ignore it?

Linux's Completely Fair Scheduler (CFS) allocates CPU proportionally to all runnable threads so no thread is indefinitely denied CPU time. Honouring strict priority would reintroduce starvation and priority inversion, which CFS was designed to prevent.

| Problem | Description | Banking Impact |
|---------|-------------|----------------|
| Priority inversion | High-priority thread waits on a lock held by a low-priority thread that never gets scheduled | Settlement thread waits on audit thread's lock |
| Starvation | Low-priority threads like audit or logging never run because high-priority work keeps arriving | Audit thread never completes, compliance violated |

What should you use instead?

Use separate thread pools for resource isolation, a PriorityBlockingQueue for application-level ordering, or cgroups/container CPU limits for hard CPU guarantees.

JAVA
package com.bank.pool;

import java.util.concurrent.*;

public class ResourceIsolation {
    // WRONG: relying on setPriority
    // settlementThread.setPriority(Thread.MAX_PRIORITY);
    // reconThread.setPriority(Thread.MIN_PRIORITY);

    // CORRECT: separate pools with explicit capacity
    private static final ExecutorService settlementPool =
        Executors.newFixedThreadPool(10);  // 10 threads dedicated to settlements
    private static final ExecutorService reconPool =
        Executors.newFixedThreadPool(2);   // 2 threads for reconciliation
}

How does PriorityBlockingQueue provide application-level ordering?

Instead of relying on OS thread scheduling, you can use a PriorityBlockingQueue to ensure high-priority tasks are processed first by the pool's workers.

JAVA
package com.bank.pool;

import java.util.concurrent.*;

public class PriorityPoolDemo {
    public static void main(String[] args) {
        PriorityBlockingQueue<Runnable> queue = new PriorityBlockingQueue<>(100);
        // Workers pull from the queue in priority order
        // This is application-level priority, not OS-level
    }
}

What about virtual threads and priority?

Virtual threads (Java 21) do not support priority at all. The virtual thread scheduler ignores setPriority(). This reinforces the point that priority is a legacy mechanism that should not be relied upon.

What are common mistakes?

The wrong approach uses setPriority for correctness or resource allocation. The correct approach uses dedicated pools, bounded queues, and application-level priority queues.

What are common interview follow-up questions?

  • How does priority inheritance in RTOS systems differ from Java? Real-time operating systems implement priority inheritance: when a low-priority thread holds a lock needed by a high-priority thread, the low-priority thread temporarily inherits the high priority. Java does not have this mechanism.
  • Can you change a thread's priority while it is running? Yes, setPriority() can be called at any time, but the effect depends on the OS scheduler.
  • How do virtual threads handle priority? They ignore it entirely. The virtual thread scheduler uses a work-stealing ForkJoinPool.

Visual Overview

DIAGRAM
  Java Priority (1-10)         OS Scheduler
  ┌─────────────────┐          ┌─────────────────┐
  │ 10 MAX_PRIORITY │──────┐   │ Linux CFS:      │
  │  9              │──────┤   │ Ignores hint,   │
  │  8              │──────┤   │ fair allocation  │
  │  7              │──────┤   │                  │
  │  6              │──────┤──▶│ Several Java     │
  │  5 NORM_PRIORITY│──────┤   │ levels collapse  │
  │  4              │──────┤   │ to same OS level │
  │  3              │──────┤   │                  │
  │  2              │──────┤   │ Windows: 7 levels│
  │  1 MIN_PRIORITY │──────┘   │ macOS: different │
  └─────────────────┘          └─────────────────┘

  Better Alternative:
  ┌───────────────┐  ┌───────────────┐
  │ Settlement    │  │ Reconciliation│
  │ Pool: 10 thds │  │ Pool: 2 thds  │
  │ Dedicated CPU │  │ Limited CPU   │
  └───────────────┘  └───────────────┘

Key Takeaway

Thread priority in Java is an integer hint between one and ten that you set with setPriority. The three constants MIN_PRIORITY, NORM_PRIORITY, and MAX_PRIORITY avoid magic numbers. A new thread inherits the priority of the creating thread, not necessarily the default five.

The single most important thing to say is that priority is only a hint and the JLS guarantees nothing. The JVM maps ten Java levels onto whatever model the host OS offers, and several levels can collapse to the same OS level. Linux CFS ignores the hint to ensure fairness.

At National Bank of India a developer tried maxing settlement's priority and minimising reconciliation's, and on Linux it did nothing. The real fix was separate thread pools with dedicated capacity.

Remember one sentence: thread priority is a hint the OS can ignore, so control resource allocation with separate thread pools and bounded queues, never with setPriority.

---

Share
Use ← → arrow keys to navigate