Table of Contents
- Introduction to Thread Priority
- Thread Priority Constants
- Setting and Getting Priority
- Priority Scheduling Behavior
- Platform Dependence
- Priority Best Practices
- Real-World Examples
Introduction to Thread Priority
Thread priority in Java is a hint to the thread scheduler about which threads are more important and should be given preference in CPU time allocation. However, it's important to note that thread priority is just a suggestion and the actual behavior depends on the underlying operating system.
Basic Concepts
public class ThreadPriorityIntroduction {
public static void main(String[] args) {
System.out.println("=== Thread Priority Introduction ===");
// Main thread priority
Thread mainThread = Thread.currentThread();
System.out.println("Main thread priority: " + mainThread.getPriority());
System.out.println("Main thread name: " + mainThread.getName());
// Default priority for new threads
Thread defaultThread = new Thread(() -> {});
System.out.println("Default thread priority: " + defaultThread.getPriority());
// Priority range information
System.out.println("Min priority: " + Thread.MIN_PRIORITY);
System.out.println("Norm priority: " + Thread.NORM_PRIORITY);
System.out.println("Max priority: " + Thread.MAX_PRIORITY);
}
}
Thread Priority Constants
Priority Range and Constants
public class ThreadPriorityConstants {
public static void main(String[] args) {
System.out.println("=== Thread Priority Constants ===");
// Priority constants
System.out.println("MIN_PRIORITY: " + Thread.MIN_PRIORITY);
System.out.println("NORM_PRIORITY: " + Thread.NORM_PRIORITY);
System.out.println("MAX_PRIORITY: " + Thread.MAX_PRIORITY);
// Valid priority range
System.out.println("Valid priority range: " + Thread.MIN_PRIORITY + " to " + Thread.MAX_PRIORITY);
// Creating threads with different priorities
Thread minThread = new Thread(() -> System.out.println("Min priority thread"));
Thread normThread = new Thread(() -> System.out.println("Normal priority thread"));
Thread maxThread = new Thread(() -> System.out.println("Max priority thread"));
minThread.setPriority(Thread.MIN_PRIORITY);
normThread.setPriority(Thread.NORM_PRIORITY);
maxThread.setPriority(Thread.MAX_PRIORITY);
System.out.println("Min thread priority: " + minThread.getPriority());
System.out.println("Norm thread priority: " + normThread.getPriority());
System.out.println("Max thread priority: " + maxThread.getPriority());
// Starting threads to see behavior
minThread.start();
normThread.start();
maxThread.start();
}
}
Setting and Getting Priority
Priority Management Methods
public class PriorityManagement {
static class PriorityDemoThread extends Thread {
private final String name;
private int count = 0;
public PriorityDemoThread(String name) {
this.name = name;
}
@Override
public void run() {
System.out.println(name + " starting with priority: " + getPriority());
// Simulate some work
for (int i = 0; i < 5; i++) {
count++;
try {
Thread.sleep(100); // Simulate work
} catch (InterruptedException e) {
System.out.println(name + " interrupted");
return;
}
}
System.out.println(name + " completed. Count: " + count);
}
}
public static void main(String[] args) {
System.out.println("=== Thread Priority Management ===");
// Create threads with different priorities
PriorityDemoThread lowPriorityThread = new PriorityDemoThread("Low-Priority");
PriorityDemoThread normalPriorityThread = new PriorityDemoThread("Normal-Priority");
PriorityDemoThread highPriorityThread = new PriorityDemoThread("High-Priority");
// Set priorities
lowPriorityThread.setPriority(Thread.MIN_PRIORITY);
normalPriorityThread.setPriority(Thread.NORM_PRIORITY);
highPriorityThread.setPriority(Thread.MAX_PRIORITY);
// Verify priorities
System.out.println("Low priority thread: " + lowPriorityThread.getPriority());
System.out.println("Normal priority thread: " + normalPriorityThread.getPriority());
System.out.println("High priority thread: " + highPriorityThread.getPriority());
// Start threads
lowPriorityThread.start();
normalPriorityThread.start();
highPriorityThread.start();
// Wait for all threads to complete
try {
lowPriorityThread.join();
normalPriorityThread.join();
highPriorityThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("All threads completed");
demonstratePriorityInheritance();
}
public static void demonstratePriorityInheritance() {
System.out.println("\n=== Priority Inheritance ===");
Thread parentThread = new Thread(() -> {
System.out.println("Parent thread priority: " + Thread.currentThread().getPriority());
Thread childThread = new Thread(() -> {
System.out.println("Child thread priority: " + Thread.currentThread().getPriority());
});
// Child thread inherits parent's priority by default
System.out.println("Child thread default priority: " + childThread.getPriority());
childThread.start();
try {
childThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
// Set parent thread priority
parentThread.setPriority(Thread.MAX_PRIORITY);
parentThread.start();
try {
parentThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Priority Validation and Safety
public class PriorityValidation {
public static void setSafePriority(Thread thread, int priority) {
if (priority < Thread.MIN_PRIORITY || priority > Thread.MAX_PRIORITY) {
throw new IllegalArgumentException(
"Priority must be between " + Thread.MIN_PRIORITY +
" and " + Thread.MAX_PRIORITY + ". Got: " + priority);
}
thread.setPriority(priority);
}
public static void demonstrateSafePrioritySetting() {
System.out.println("=== Safe Priority Setting ===");
Thread thread = new Thread(() -> System.out.println("Test thread"));
// Valid priority setting
try {
setSafePriority(thread, Thread.NORM_PRIORITY);
System.out.println("Priority set successfully: " + thread.getPriority());
} catch (IllegalArgumentException e) {
System.out.println("Error: " + e.getMessage());
}
// Invalid priority setting
try {
setSafePriority(thread, 0); // Too low
} catch (IllegalArgumentException e) {
System.out.println("Expected error: " + e.getMessage());
}
// Another invalid priority
try {
setSafePriority(thread, 11); // Too high
} catch (IllegalArgumentException e) {
System.out.println("Expected error: " + e.getMessage());
}
}
public static void priorityBoundsCheck() {
System.out.println("\n=== Priority Bounds Check ===");
Thread thread = new Thread(() -> {});
// Test boundary conditions
thread.setPriority(Thread.MIN_PRIORITY); // Should work
System.out.println("Min priority set: " + thread.getPriority());
thread.setPriority(Thread.MAX_PRIORITY); // Should work
System.out.println("Max priority set: " + thread.getPriority());
// Try to set out-of-bounds values directly (will be clamped by JVM)
try {
thread.setPriority(0); // Below minimum
System.out.println("Priority after setting 0: " + thread.getPriority());
} catch (Exception e) {
System.out.println("Exception when setting priority 0: " + e.getMessage());
}
try {
thread.setPriority(11); // Above maximum
System.out.println("Priority after setting 11: " + thread.getPriority());
} catch (Exception e) {
System.out.println("Exception when setting priority 11: " + e.getMessage());
}
}
public static void main(String[] args) {
demonstrateSafePrioritySetting();
priorityBoundsCheck();
}
}
Priority Scheduling Behavior
Priority Impact Demonstration
public class PrioritySchedulingBehavior {
static class CountingThread extends Thread {
private final String name;
private long count = 0;
private volatile boolean running = true;
public CountingThread(String name) {
this.name = name;
}
@Override
public void run() {
System.out.println(name + " started with priority: " + getPriority());
while (running && count < 1_000_000_000L) {
count++;
}
System.out.println(name + " completed. Count: " + count);
}
public void stopCounting() {
running = false;
}
public long getCount() {
return count;
}
}
public static void demonstratePriorityImpact() {
System.out.println("=== Priority Impact Demonstration ===");
CountingThread lowPriorityThread = new CountingThread("Low-Priority");
CountingThread highPriorityThread = new CountingThread("High-Priority");
lowPriorityThread.setPriority(Thread.MIN_PRIORITY);
highPriorityThread.setPriority(Thread.MAX_PRIORITY);
// Start threads
highPriorityThread.start();
lowPriorityThread.start();
// Let them run for 2 seconds
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// Stop threads
lowPriorityThread.stopCounting();
highPriorityThread.stopCounting();
// Wait for threads to finish
try {
lowPriorityThread.join();
highPriorityThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
// Display results
System.out.println("\nResults after 2 seconds:");
System.out.println("High priority thread count: " + highPriorityThread.getCount());
System.out.println("Low priority thread count: " + lowPriorityThread.getCount());
System.out.println("Ratio: " +
(double) highPriorityThread.getCount() / lowPriorityThread.getCount());
// Note: Results may vary significantly based on OS and system load
}
public static void priorityWithSleep() {
System.out.println("\n=== Priority with Sleep ===");
Thread lowPriority = new Thread(() -> {
for (int i = 0; i < 5; i++) {
System.out.println("Low priority working...");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
break;
}
}
});
Thread highPriority = new Thread(() -> {
for (int i = 0; i < 5; i++) {
System.out.println("HIGH priority working...");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
break;
}
}
});
lowPriority.setPriority(Thread.MIN_PRIORITY);
highPriority.setPriority(Thread.MAX_PRIORITY);
highPriority.start();
lowPriority.start();
try {
highPriority.join();
lowPriority.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Both threads completed");
}
public static void main(String[] args) {
demonstratePriorityImpact();
priorityWithSleep();
}
}
CPU-intensive vs I/O-intensive Threads
public class CPUvsIOThreads {
static class CPUIntensiveThread extends Thread {
private final String name;
private long computations = 0;
public CPUIntensiveThread(String name) {
this.name = name;
}
@Override
public void run() {
System.out.println(name + " (CPU-intensive) started");
long startTime = System.currentTimeMillis();
// CPU-intensive work
while (System.currentTimeMillis() - startTime < 3000) { // Run for 3 seconds
computations++;
// Pure computation - no I/O
Math.pow(computations, 0.5);
}
System.out.println(name + " completed. Computations: " + computations);
}
}
static class IOIntensiveThread extends Thread {
private final String name;
private int operations = 0;
public IOIntensiveThread(String name) {
this.name = name;
}
@Override
public void run() {
System.out.println(name + " (I/O-intensive) started");
long startTime = System.currentTimeMillis();
// I/O-intensive work
while (System.currentTimeMillis() - startTime < 3000) { // Run for 3 seconds
operations++;
try {
Thread.sleep(10); // Simulate I/O wait
} catch (InterruptedException e) {
break;
}
}
System.out.println(name + " completed. I/O operations: " + operations);
}
}
public static void demonstratePriorityEffect() {
System.out.println("=== CPU vs I/O Intensive Threads ===");
// CPU-intensive threads
CPUIntensiveThread cpuLow = new CPUIntensiveThread("CPU-Low");
CPUIntensiveThread cpuHigh = new CPUIntensiveThread("CPU-High");
cpuLow.setPriority(Thread.MIN_PRIORITY);
cpuHigh.setPriority(Thread.MAX_PRIORITY);
// I/O-intensive threads
IOIntensiveThread ioLow = new IOIntensiveThread("I/O-Low");
IOIntensiveThread ioHigh = new IOIntensiveThread("I/O-High");
ioLow.setPriority(Thread.MIN_PRIORITY);
ioHigh.setPriority(Thread.MAX_PRIORITY);
System.out.println("Starting CPU-intensive threads...");
cpuHigh.start();
cpuLow.start();
try {
cpuHigh.join();
cpuLow.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("\nStarting I/O-intensive threads...");
ioHigh.start();
ioLow.start();
try {
ioHigh.join();
ioLow.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("\nAll threads completed");
System.out.println("Note: Priority has more impact on CPU-intensive threads");
}
public static void main(String[] args) {
demonstratePriorityEffect();
}
}
Platform Dependence
Platform-Specific Behavior
public class PlatformDependence {
public static void analyzePlatformBehavior() {
System.out.println("=== Platform Dependence Analysis ===");
// Get system information
String osName = System.getProperty("os.name");
String osVersion = System.getProperty("os.version");
String javaVersion = System.getProperty("java.version");
System.out.println("Operating System: " + osName);
System.out.println("OS Version: " + osVersion);
System.out.println("Java Version: " + javaVersion);
System.out.println("Available Processors: " + Runtime.getRuntime().availableProcessors());
// Test how priorities are handled
testPriorityHandling();
}
public static void testPriorityHandling() {
System.out.println("\n=== Priority Handling Test ===");
Thread[] threads = new Thread[5];
for (int i = 0; i < threads.length; i++) {
final int threadNum = i;
threads[i] = new Thread(() -> {
String threadName = "Thread-" + threadNum;
int priority = Thread.MIN_PRIORITY + threadNum;
Thread.currentThread().setPriority(priority);
System.out.println(threadName + " set priority to: " + priority);
// Do some work
long sum = 0;
for (int j = 0; j < 1000000; j++) {
sum += j;
}
System.out.println(threadName + " completed with actual priority: " +
Thread.currentThread().getPriority());
});
}
// Start all threads
for (Thread thread : threads) {
thread.start();
}
// Wait for completion
for (Thread thread : threads) {
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("\nPriority test completed");
System.out.println("Note: Some OS may ignore or modify Java thread priorities");
}
public static void windowsVsUnixBehavior() {
System.out.println("\n=== Windows vs Unix/Linux Behavior ===");
String os = System.getProperty("os.name").toLowerCase();
if (os.contains("windows")) {
System.out.println("Windows detected - Thread priorities are mapped to Windows priority classes:");
System.out.println(" MIN_PRIORITY (1) -> THREAD_PRIORITY_LOWEST");
System.out.println(" NORM_PRIORITY (5) -> THREAD_PRIORITY_NORMAL");
System.out.println(" MAX_PRIORITY (10) -> THREAD_PRIORITY_HIGHEST");
} else if (os.contains("linux") || os.contains("unix") || os.contains("mac")) {
System.out.println("Unix/Linux/Mac detected - Thread priorities may have limited effect:");
System.out.println(" Priorities are hints, actual scheduling depends on system load");
System.out.println(" Some Linux distributions may ignore Java thread priorities entirely");
} else {
System.out.println("Unknown OS - Priority behavior may vary");
}
}
public static void main(String[] args) {
analyzePlatformBehavior();
windowsVsUnixBehavior();
}
}
Real Platform Testing
public class RealPriorityTest {
static class PriorityTestThread extends Thread {
private final int targetPriority;
private long workUnits = 0;
private volatile boolean running = true;
public PriorityTestThread(int priority) {
this.targetPriority = priority;
setPriority(priority);
}
@Override
public void run() {
System.out.println(getName() + " starting with priority " + getPriority());
long startTime = System.currentTimeMillis();
while (running && System.currentTimeMillis() - startTime < 5000) {
workUnits++;
// Some computation to keep CPU busy
for (int i = 0; i < 1000; i++) {
Math.sin(i);
}
}
System.out.println(getName() + " completed: " + workUnits + " work units");
}
public void stopTest() {
running = false;
}
}
public static void conductPriorityTest() {
System.out.println("=== Real Priority Effectiveness Test ===");
// Create threads with different priorities
PriorityTestThread[] threads = new PriorityTestThread[3];
threads[0] = new PriorityTestThread(Thread.MIN_PRIORITY);
threads[1] = new PriorityTestThread(Thread.NORM_PRIORITY);
threads[2] = new PriorityTestThread(Thread.MAX_PRIORITY);
threads[0].setName("Low-Priority");
threads[1].setName("Normal-Priority");
threads[2].setName("High-Priority");
// Start all threads
for (Thread thread : threads) {
thread.start();
}
// Let them run for 5 seconds
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// Stop threads
for (PriorityTestThread thread : threads) {
thread.stopTest();
}
// Wait for completion
for (PriorityTestThread thread : threads) {
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// Analyze results
System.out.println("\n=== Test Results ===");
long lowWork = threads[0].workUnits;
long normalWork = threads[1].workUnits;
long highWork = threads[2].workUnits;
long totalWork = lowWork + normalWork + highWork;
System.out.printf("Low priority: %10d work units (%5.2f%%)%n",
lowWork, (lowWork * 100.0 / totalWork));
System.out.printf("Normal priority: %10d work units (%5.2f%%)%n",
normalWork, (normalWork * 100.0 / totalWork));
System.out.printf("High priority: %10d work units (%5.2f%%)%n",
highWork, (highWork * 100.0 / totalWork));
System.out.println("\nInterpretation:");
if (highWork > normalWork && normalWork > lowWork) {
System.out.println("✓ Thread priorities are working effectively on this platform");
} else {
System.out.println("⚠ Thread priorities may not be effective on this platform");
System.out.println(" (This is common on some Unix/Linux systems)");
}
}
public static void main(String[] args) {
conductPriorityTest();
}
}
Priority Best Practices
Thread Priority Guidelines
public class PriorityBestPractices {
public static void demonstrateBestPractices() {
System.out.println("=== Thread Priority Best Practices ===");
// 1. Use priorities sparingly
System.out.println("\n1. Use Priorities Sparingly:");
System.out.println(" - Only use when you have a good reason");
System.out.println(" - Overuse can lead to thread starvation");
// 2. Prefer NORM_PRIORITY for most threads
System.out.println("\n2. Prefer NORM_PRIORITY:");
Thread normalThread = new Thread(() -> System.out.println("Normal priority task"));
normalThread.setPriority(Thread.NORM_PRIORITY);
System.out.println(" Most threads should use NORM_PRIORITY (" + Thread.NORM_PRIORITY + ")");
// 3. Use MAX_PRIORITY for critical tasks
System.out.println("\n3. Use MAX_PRIORITY for Critical Tasks:");
Thread criticalThread = new Thread(() -> {
System.out.println("Critical task - should complete quickly");
// Emergency shutdown, user input processing, etc.
});
criticalThread.setPriority(Thread.MAX_PRIORITY);
System.out.println(" Reserve MAX_PRIORITY for truly critical operations");
// 4. Use MIN_PRIORITY for background tasks
System.out.println("\n4. Use MIN_PRIORITY for Background Tasks:");
Thread backgroundThread = new Thread(() -> {
System.out.println("Background task - can run when system is idle");
// Logging, cleanup, monitoring, etc.
});
backgroundThread.setPriority(Thread.MIN_PRIORITY);
System.out.println(" Use MIN_PRIORITY for non-urgent background work");
// Start demonstration threads
criticalThread.start();
normalThread.start();
backgroundThread.start();
try {
criticalThread.join();
normalThread.join();
backgroundThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void commonMistakes() {
System.out.println("\n=== Common Priority Mistakes ===");
// Mistake 1: Setting all threads to high priority
System.out.println("\n1. Setting All Threads to High Priority:");
System.out.println(" ❌ If all threads are high priority, none are high priority");
System.out.println(" ✅ Use priorities to establish relative importance");
// Mistake 2: Relying too much on priorities
System.out.println("\n2. Over-relying on Priorities:");
System.out.println(" ❌ Assuming high priority guarantees immediate execution");
System.out.println(" ✅ Priorities are hints, not guarantees");
// Mistake 3: Ignoring platform differences
System.out.println("\n3. Ignoring Platform Differences:");
System.out.println(" ❌ Writing code that depends on specific priority behavior");
System.out.println(" ✅ Test on target platforms and have fallback behavior");
// Mistake 4: Using priorities for synchronization
System.out.println("\n4. Using Priorities for Synchronization:");
System.out.println(" ❌ Using priorities to control execution order");
System.out.println(" ✅ Use proper synchronization mechanisms (locks, semaphores)");
}
public static void prioritySafetyPatterns() {
System.out.println("\n=== Priority Safety Patterns ===");
// Pattern 1: Temporary priority boost
System.out.println("\n1. Temporary Priority Boost:");
Thread workerThread = new Thread(() -> {
int originalPriority = Thread.currentThread().getPriority();
try {
// Boost priority for critical section
Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
System.out.println("Working in high priority mode");
// Critical work here
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
// Always restore original priority
Thread.currentThread().setPriority(originalPriority);
System.out.println("Restored original priority: " + originalPriority);
}
});
workerThread.start();
try {
workerThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
// Pattern 2: Priority-based task execution
System.out.println("\n2. Priority-based Task Execution:");
ExecutorService priorityExecutor = java.util.concurrent.Executors.newFixedThreadPool(3);
for (int i = 1; i <= 5; i++) {
final int taskId = i;
int priority = (taskId % 2 == 0) ? Thread.MAX_PRIORITY : Thread.NORM_PRIORITY;
priorityExecutor.execute(() -> {
Thread.currentThread().setPriority(priority);
System.out.println("Task " + taskId + " running with priority " + priority);
});
}
priorityExecutor.shutdown();
try {
priorityExecutor.awaitTermination(2, java.util.concurrent.TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
demonstrateBestPractices();
commonMistakes();
prioritySafetyPatterns();
}
}
Advanced Priority Management
import java.util.*;
import java.util.concurrent.*;
public class AdvancedPriorityManagement {
static class PriorityAwareExecutor {
private final ExecutorService executor;
private final Map<Runnable, Integer> taskPriorities = new ConcurrentHashMap<>();
public PriorityAwareExecutor(int poolSize) {
this.executor = Executors.newFixedThreadPool(poolSize, new PriorityThreadFactory());
}
public void submit(Runnable task, int priority) {
taskPriorities.put(task, priority);
executor.execute(() -> {
Thread currentThread = Thread.currentThread();
int originalPriority = currentThread.getPriority();
try {
// Set task-specific priority
currentThread.setPriority(priority);
task.run();
} finally {
// Restore original priority
currentThread.setPriority(originalPriority);
taskPriorities.remove(task);
}
});
}
public void shutdown() {
executor.shutdown();
}
public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException {
return executor.awaitTermination(timeout, unit);
}
private class PriorityThreadFactory implements ThreadFactory {
private final AtomicInteger threadNumber = new AtomicInteger(1);
@Override
public Thread newThread(Runnable r) {
Thread thread = new Thread(r, "PriorityThread-" + threadNumber.getAndIncrement());
thread.setPriority(Thread.NORM_PRIORITY); // Default priority
return thread;
}
}
}
static class PriorityTask implements Runnable {
private final String name;
private final int priority;
public PriorityTask(String name, int priority) {
this.name = name;
this.priority = priority;
}
@Override
public void run() {
System.out.println(name + " executing with priority " + priority);
// Simulate work
long result = 0;
for (int i = 0; i < 1000000; i++) {
result += Math.sqrt(i);
}
System.out.println(name + " completed");
}
}
public static void demonstratePriorityAwareExecutor() {
System.out.println("=== Priority-Aware Executor ===");
PriorityAwareExecutor executor = new PriorityAwareExecutor(3);
// Submit tasks with different priorities
executor.submit(new PriorityTask("Critical-1", Thread.MAX_PRIORITY), Thread.MAX_PRIORITY);
executor.submit(new PriorityTask("Normal-1", Thread.NORM_PRIORITY), Thread.NORM_PRIORITY);
executor.submit(new PriorityTask("Low-1", Thread.MIN_PRIORITY), Thread.MIN_PRIORITY);
executor.submit(new PriorityTask("Critical-2", Thread.MAX_PRIORITY), Thread.MAX_PRIORITY);
executor.submit(new PriorityTask("Normal-2", Thread.NORM_PRIORITY), Thread.NORM_PRIORITY);
executor.shutdown();
try {
executor.awaitTermination(5, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("All tasks completed");
}
static class DynamicPriorityThread extends Thread {
private volatile int dynamicPriority;
private final Object priorityLock = new Object();
public DynamicPriorityThread(Runnable target, int initialPriority) {
super(target);
this.dynamicPriority = initialPriority;
setPriority(initialPriority);
}
public void setDynamicPriority(int newPriority) {
synchronized (priorityLock) {
if (newPriority >= Thread.MIN_PRIORITY && newPriority <= Thread.MAX_PRIORITY) {
this.dynamicPriority = newPriority;
setPriority(newPriority);
System.out.println(getName() + " priority changed to: " + newPriority);
}
}
}
public int getDynamicPriority() {
synchronized (priorityLock) {
return dynamicPriority;
}
}
}
public static void demonstrateDynamicPriority() {
System.out.println("\n=== Dynamic Priority Adjustment ===");
DynamicPriorityThread thread = new DynamicPriorityThread(() -> {
for (int i = 0; i < 10; i++) {
System.out.println("Working... current priority: " +
Thread.currentThread().getPriority());
try {
Thread.sleep(500);
} catch (InterruptedException e) {
break;
}
}
}, Thread.NORM_PRIORITY);
thread.start();
// Change priority dynamically
try {
Thread.sleep(1000);
thread.setDynamicPriority(Thread.MAX_PRIORITY);
Thread.sleep(1500);
thread.setDynamicPriority(Thread.MIN_PRIORITY);
Thread.sleep(1500);
thread.setDynamicPriority(Thread.NORM_PRIORITY);
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Dynamic priority demonstration completed");
}
public static void main(String[] args) {
demonstratePriorityAwareExecutor();
demonstrateDynamicPriority();
}
}
Real-World Examples
Real-Time System Simulation
public class RealTimeSystemSimulation {
static class RealTimeTask extends Thread {
private final String taskName;
private final int periodMs; // Execution period
private final int deadlineMs; // Relative deadline
private volatile boolean running = true;
public RealTimeTask(String name, int period, int priority) {
this.taskName = name;
this.periodMs = period;
this.deadlineMs = period; // Deadline equals period for simplicity
setPriority(priority);
setName(name);
}
@Override
public void run() {
System.out.println(taskName + " started (Priority: " + getPriority() + ")");
long startTime = System.currentTimeMillis();
int cycle = 0;
while (running && cycle < 10) {
long cycleStart = System.currentTimeMillis();
// Simulate task execution
simulateWork();
long executionTime = System.currentTimeMillis() - cycleStart;
long deadline = cycleStart + deadlineMs;
// Check if deadline was met
if (System.currentTimeMillis() > deadline) {
System.out.println(taskName + " cycle " + cycle + " MISSED DEADLINE!");
} else {
System.out.println(taskName + " cycle " + cycle + " completed on time");
}
// Sleep until next period
long nextStart = startTime + (cycle + 1) * periodMs;
long sleepTime = nextStart - System.currentTimeMillis();
if (sleepTime > 0) {
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
break;
}
}
cycle++;
}
System.out.println(taskName + " completed");
}
private void simulateWork() {
// Simulate variable execution time
long work = 0;
for (int i = 0; i < 1000000 + (int)(Math.random() * 500000); i++) {
work += Math.sqrt(i);
}
}
public void stopTask() {
running = false;
interrupt();
}
}
public static void simulateRealTimeSystem() {
System.out.println("=== Real-Time System Simulation ===");
// Create real-time tasks with different priorities and periods
RealTimeTask highPriorityTask = new RealTimeTask("High-Priority-Task", 100, Thread.MAX_PRIORITY);
RealTimeTask mediumPriorityTask = new RealTimeTask("Medium-Priority-Task", 150, Thread.NORM_PRIORITY);
RealTimeTask lowPriorityTask = new RealTimeTask("Low-Priority-Task", 200, Thread.MIN_PRIORITY);
System.out.println("Starting real-time tasks...");
highPriorityTask.start();
mediumPriorityTask.start();
lowPriorityTask.start();
// Let the system run for 5 seconds
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// Stop all tasks
highPriorityTask.stopTask();
mediumPriorityTask.stopTask();
lowPriorityTask.stopTask();
try {
highPriorityTask.join();
mediumPriorityTask.join();
lowPriorityTask.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Real-time simulation completed");
}
static class UserInterfaceSimulation {
public static void simulateUIApplication() {
System.out.println("\n=== User Interface Application Simulation ===");
// UI Thread (high priority for responsiveness)
Thread uiThread = new Thread(() -> {
Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
System.out.println("UI Thread started (Priority: " + Thread.currentThread().getPriority() + ")");
for (int i = 0; i < 5; i++) {
System.out.println("UI: Processing user input...");
try {
Thread.sleep(200);
} catch (InterruptedException e) {
break;
}
}
System.out.println("UI Thread completed");
});
// Background worker (low priority)
Thread backgroundWorker = new Thread(() -> {
Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
System.out.println("Background Worker started (Priority: " + Thread.currentThread().getPriority() + ")");
for (int i = 0; i < 10; i++) {
System.out.println("Background: Performing non-critical work...");
try {
Thread.sleep(300);
} catch (InterruptedException e) {
break;
}
}
System.out.println("Background Worker completed");
});
// Network service (normal priority)
Thread networkService = new Thread(() -> {
Thread.currentThread().setPriority(Thread.NORM_PRIORITY);
System.out.println("Network Service started (Priority: " + Thread.currentThread().getPriority() + ")");
for (int i = 0; i < 7; i++) {
System.out.println("Network: Handling request...");
try {
Thread.sleep(250);
} catch (InterruptedException e) {
break;
}
}
System.out.println("Network Service completed");
});
uiThread.start();
networkService.start();
backgroundWorker.start();
try {
uiThread.join();
networkService.join();
backgroundWorker.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("UI application simulation completed");
}
}
public static void main(String[] args) {
simulateRealTimeSystem();
UserInterfaceSimulation.simulateUIApplication();
}
}
Game Development Example
public class GameDevelopmentExample {
static class GameEngine {
private volatile boolean running = false;
private Thread gameLoopThread;
private Thread physicsThread;
private Thread renderingThread;
private Thread aiThread;
public void start() {
System.out.println("=== Game Engine Starting ===");
running = true;
// Game loop thread (highest priority - controls game state)
gameLoopThread = new Thread(() -> {
Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
System.out.println("Game Loop started (Priority: " + Thread.currentThread().getPriority() + ")");
long lastTime = System.nanoTime();
double nsPerUpdate = 1000000000.0 / 60.0; // 60 updates per second
while (running) {
long now = System.nanoTime();
// Game state update
updateGameState();
// Sleep to maintain frame rate
long sleepTime = (long)((lastTime + nsPerUpdate - now) / 1000000);
if (sleepTime > 0) {
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
break;
}
}
lastTime = now;
}
System.out.println("Game Loop stopped");
});
// Physics thread (high priority - affects game mechanics)
physicsThread = new Thread(() -> {
Thread.currentThread().setPriority(Thread.MAX_PRIORITY - 1);
System.out.println("Physics Thread started (Priority: " + Thread.currentThread().getPriority() + ")");
while (running) {
updatePhysics();
try {
Thread.sleep(16); // ~60 physics updates per second
} catch (InterruptedException e) {
break;
}
}
System.out.println("Physics Thread stopped");
});
// Rendering thread (normal priority - can be interrupted)
renderingThread = new Thread(() -> {
Thread.currentThread().setPriority(Thread.NORM_PRIORITY);
System.out.println("Rendering Thread started (Priority: " + Thread.currentThread().getPriority() + ")");
while (running) {
renderFrame();
try {
Thread.sleep(33); // ~30 frames per second
} catch (InterruptedException e) {
break;
}
}
System.out.println("Rendering Thread stopped");
});
// AI thread (low priority - background processing)
aiThread = new Thread(() -> {
Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
System.out.println("AI Thread started (Priority: " + Thread.currentThread().getPriority() + ")");
while (running) {
updateAI();
try {
Thread.sleep(100); // 10 AI updates per second
} catch (InterruptedException e) {
break;
}
}
System.out.println("AI Thread stopped");
});
// Start threads in priority order
gameLoopThread.start();
physicsThread.start();
renderingThread.start();
aiThread.start();
}
public void stop() {
System.out.println("=== Game Engine Stopping ===");
running = false;
try {
gameLoopThread.join(1000);
physicsThread.join(1000);
renderingThread.join(1000);
aiThread.join(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void updateGameState() {
// Simulate game state update
// System.out.println("Updating game state...");
}
private void updatePhysics() {
// Simulate physics calculation
// System.out.println("Updating physics...");
}
private void renderFrame() {
// Simulate rendering
// System.out.println("Rendering frame...");
}
private void updateAI() {
// Simulate AI processing
// System.out.println("Updating AI...");
}
}
public static void demonstrateGameEngine() {
System.out.println("=== Game Engine Priority Demonstration ===");
GameEngine engine = new GameEngine();
engine.start();
// Let the game run for 3 seconds
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
engine.stop();
System.out.println("Game engine demonstration completed");
}
static class PerformanceMonitor extends Thread {
private final GameEngine engine;
private volatile boolean monitoring = true;
public PerformanceMonitor(GameEngine engine) {
this.engine = engine;
setPriority(Thread.MAX_PRIORITY);
setName("Performance-Monitor");
}
@Override
public void run() {
System.out.println("Performance Monitor started");
long lastCheck = System.currentTimeMillis();
int checks = 0;
while (monitoring && checks < 20) {
// Monitor thread states and performance
monitorThreadPerformance();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
break;
}
checks++;
}
System.out.println("Performance Monitor stopped");
}
private void monitorThreadPerformance() {
// In a real implementation, you would collect metrics
// about thread execution times, frame rates, etc.
// System.out.println("Monitoring performance...");
}
public void stopMonitoring() {
monitoring = false;
interrupt();
}
}
public static void main(String[] args) {
demonstrateGameEngine();
}
}
Summary
Key Points about Thread Priority in Java:
- Priority Range: 1 (MIN_PRIORITY) to 10 (MAX_PRIORITY), with 5 as NORM_PRIORITY
- Platform Dependence: Behavior varies across operating systems
- Suggestion, Not Guarantee: Priorities are hints to the scheduler
- Inheritance: Child threads inherit parent thread priority
- Use Cases:
- MAX_PRIORITY: Critical tasks, user interfaces, real-time systems
- NORM_PRIORITY: Most application threads
- MIN_PRIORITY: Background tasks, maintenance operations
Best Practices:
- Use priorities judiciously
- Test on target platforms
- Don't rely on priorities for correctness
- Use proper synchronization instead of priorities for coordination
- Consider using higher-level concurrency utilities from
java.util.concurrent
Thread priority can be a useful tool for performance optimization in specific scenarios, but it should be used with caution and understanding of its limitations.