-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathThreadPriority.java
More file actions
129 lines (117 loc) · 4.76 KB
/
Copy pathThreadPriority.java
File metadata and controls
129 lines (117 loc) · 4.76 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package Phase7_Concurrency.Multithreading;
/**
* Thread Priority
* ---------------
* Every Thread has an integer PRIORITY between 1 and 10 (inclusive):
* <p>
*
* Thread.MIN_PRIORITY = 1
* Thread.NORM_PRIORITY = 5 (the default)
* Thread.MAX_PRIORITY = 10
* <p>
*
* Priority is a HINT to the OS scheduler that this thread should be
* preferred over lower-priority ones. It is NOT a guarantee.
* <p>
*
* What actually happens
* ---------------------
* - The JVM maps Java's 1..10 to native OS priorities. Each OS has a
* different range and policy:
* Linux - mapping varies, often a small effect or none in CFS.
* Windows - mapped to thread priority levels (idle..time-critical).
* macOS - QoS-influenced; not a strict ordering.
* - On most modern desktops/servers, priority has very little effect.
* Do NOT rely on it for correctness.
* <p>
*
* Inheritance
* -----------
* A new Thread inherits its priority from the thread that created it
* (unless explicitly set before start()).
* <p>
*
* Validity
* --------
* setPriority(int) throws IllegalArgumentException if out of [1, 10].
* setPriority is also capped by the parent ThreadGroup's max priority.
* <p>
*
* When NOT to use priorities
* --------------------------
* - To "make this thread go faster than another." It rarely does.
* - To ensure ordering or fairness — use a queue / synchronizer.
* - To prevent starvation — priority-based starvation is a thing.
* <p>
*
* When priorities can help
* ------------------------
* - To run a low-priority background task (Thread.MIN_PRIORITY) so it
* doesn't crowd out interactive work.
* - On dedicated real-time-ish systems where you actually control the
* OS scheduler. On general-purpose JVMs, treat priorities as polite
* hints only.
*/
public class ThreadPriority {
public static void main(String[] args) throws InterruptedException {
section("1) Constants and defaults");
System.out.println("MIN = " + Thread.MIN_PRIORITY);
System.out.println("NORM = " + Thread.NORM_PRIORITY);
System.out.println("MAX = " + Thread.MAX_PRIORITY);
System.out.println("main priority = " + Thread.currentThread().getPriority());
section("2) Get/set");
Thread t = new Thread(() -> {}, "p-demo");
System.out.println("initial = " + t.getPriority());
t.setPriority(Thread.MAX_PRIORITY);
System.out.println("after MAX = " + t.getPriority());
section("3) Out-of-range throws");
try { t.setPriority(11); }
catch (IllegalArgumentException e) { System.out.println("expected: " + e); }
section("4) Inheritance — child inherits parent's priority");
Thread parent = new Thread(() -> {
Thread child = new Thread(() -> {}, "child");
System.out.println("parent priority = " + Thread.currentThread().getPriority());
System.out.println("child priority = " + child.getPriority());
}, "parent");
parent.setPriority(7);
parent.start();
parent.join();
section("5) HIGH vs LOW — observe (or fail to observe) effect");
// Two threads compute; the higher-priority one MAY get more cycles.
// On many systems you'll see NO difference. Don't depend on this.
long[] counts = new long[2];
Thread hi = new Thread(() -> counts[0] = busy(800));
Thread lo = new Thread(() -> counts[1] = busy(800));
hi.setPriority(Thread.MAX_PRIORITY);
lo.setPriority(Thread.MIN_PRIORITY);
hi.start(); lo.start();
hi.join(); lo.join();
System.out.println("hi count = " + counts[0]);
System.out.println("lo count = " + counts[1]);
System.out.println("(any difference is OS-dependent and not guaranteed)");
section("6) Background task pattern");
Thread cleanup = new Thread(() -> {
// pretend GC, log flushing, cache refresh, etc.
for (int i = 0; i < 3; i++) {
System.out.println(" cleanup pass " + i);
try { Thread.sleep(30); } catch (InterruptedException ignored) {}
}
}, "cleanup");
cleanup.setPriority(Thread.MIN_PRIORITY);
cleanup.setDaemon(true); // don't keep JVM alive
cleanup.start();
cleanup.join();
section("done");
}
/** Count as many increments as fit in ms milliseconds. */
private static long busy(long ms) {
long end = System.currentTimeMillis() + ms;
long n = 0;
while (System.currentTimeMillis() < end) n++;
return n;
}
private static void section(String title) {
System.out.println();
System.out.println("=== " + title + " ===");
}
}