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.