Reputation: 1030
I have set thread's priority in below order
A then B then C .But when I am running below program sometimes B runs before A. I don't understand this execution as I set B's priority less then A's priority.
public class AThread implements Runnable{
public void run(){
System.out.println("In thread A");
}}
public class BThread implements Runnable {
public void run(){
System.out.println("In thread B");
}
}
public class CThread implements Runnable {
public void run(){
System.out.println("In thread C");
}
}
public class ThreadPriorityDemo {
public static void main(String args[]){
AThread A = new AThread();
Thread tA = new Thread(A);
BThread B = new BThread();
Thread tB = new Thread(B);
CThread C = new CThread();
Thread tC = new Thread(C);
tA.setPriority(Thread.MAX_PRIORITY);
tC.setPriority(Thread.MIN_PRIORITY);
tB.setPriority(tA.getPriority() -1);
System.out.println("A started");
tA.start();
System.out.println("B started");
tB.start();
System.out.println("C started");
tC.start();
}
}
Upvotes: 3
Views: 2176
Reputation: 1578
If you need to execute threads with exact order, you can't do this with thread priority. You can use to one of the synchronization supports. (e.g Locks, semaphores).
Upvotes: 3
Reputation: 15408
I think the proper answer is: You cannot reliably order thread start by setting thread priority.
I think your confusion stems from the fact that the documentation states
Threads with higher priority are executed in preference to threads with lower priority.
While this is true, it only refers to threads that are doing computation (or, on some operating systems, waiting for a shared resource). In such cases, threads with higher priority will receive more CPU time, i.e. will be executed in preference to threads that compete for the same resource.
Even if the thread priority would influence the order in which your threads are started (it most likely doesn't), all your threads could actually really run in parallel on modern CPUs as they don't influence each other.
In fact, the order of execution is determined by some other factor entirely: The threads don't do any relevant computation, they spent most of their (really small) execution time waiting for a shared resource, namely System.out
.
One has to look at the code to find that the code underlying System.out
, which is PrintStream
actually does atomic, synchronized writes:
public void write(byte buf[], int off, int len) {
try {
synchronized (this) {
ensureOpen();
out.write(buf, off, len);
if (autoFlush)
out.flush();
}
}
catch (InterruptedIOException x) {
Thread.currentThread().interrupt();
}
catch (IOException x) {
trouble = true;
}
}
So what happens is that the first thread that reaches the println()
blocks all other threads until it is done with writing its output. First thread winds regardless of priority because you cannot interrupt a synchronized block (that would defeat the purpose of the monitor).
Which thread gets the lock first depends on more factors than just thread priority and maybe even not on the (Java) thread priority at all.
Upvotes: 2
Reputation: 34648
Thread priorities are probably not what you think they are.
A thread's priority is a recommendation to the operating system to prefer one thread over another in any scheduling or CPU allocation decision point where these two threads are involved. But how this is implemented depends on the operating system and the JVM implementation.
JavaMex has a nice discussion of thread priorities. The gist is that:
Be sure to read the next article after that, which shows you how it's done on Linux and Windows.
I think your problem may stem from the third point above (if you're running on Windows), but it may be any of the other reasons.
Upvotes: 3