why the low priority thread is executed first [duplicate] - java

This is a test about thread priority.
The code is from Thinking in Java p.809
import java.util.concurrent.*;
public class SimplePriorities implements Runnable {
private int countDown = 5;
private volatile double d; // No optimization
private int priority;
public SimplePriorities(int priority) {
this.priority = priority;
}
public String toString() {
return Thread.currentThread() + ": " + countDown;
}
public void run() {
Thread.currentThread().setPriority(priority);
while (true) {
// An expensive, interruptable operation:
for (int i = 1; i < 10000000; i++) {
d += (Math.PI + Math.E) / (double) i;
if (i % 1000 == 0)
Thread.yield();
}
System.out.println(this);
if (--countDown == 0)
return;
}
}
public static void main(String[] args) {
ExecutorService exec = Executors.newCachedThreadPool();
for (int i = 0; i < 5; i++)
exec.execute(new SimplePriorities(Thread.MIN_PRIORITY));
exec.execute(new SimplePriorities(Thread.MAX_PRIORITY));
exec.shutdown();
}
}
I wonder why I can't get a regular result like:
Thread[pool-1-thread-6,10,main]: 5
Thread[pool-1-thread-6,10,main]: 4
Thread[pool-1-thread-6,10,main]: 3
Thread[pool-1-thread-6,10,main]: 2
Thread[pool-1-thread-6,10,main]: 1
Thread[pool-1-thread-3,1,main]: 5
Thread[pool-1-thread-2,1,main]: 5
Thread[pool-1-thread-1,1,main]: 5
Thread[pool-1-thread-5,1,main]: 5
Thread[pool-1-thread-4,1,main]: 5
...
but a random result (every time I run it changes):
Thread[pool-1-thread-2,1,main]: 5
Thread[pool-1-thread-3,1,main]: 5
Thread[pool-1-thread-4,1,main]: 5
Thread[pool-1-thread-2,1,main]: 4
Thread[pool-1-thread-3,1,main]: 4
Thread[pool-1-thread-1,1,main]: 5
Thread[pool-1-thread-6,10,main]: 5
Thread[pool-1-thread-5,1,main]: 5
...
I use i3-2350M 2C4T CPU with Win 7 64 bit JDK 7.
Does it matter ?

Java Thread priority has no effect
Thread priorities are highly OS specific and on many operating systems often have minimal effect. Priorities help to order the threads that are in the run queue only and will not change how often the threads are run in any major way unless you are doing a ton of CPU in each of the threads.
Your program looks to use a lot of CPU but unless you have fewer cores than there are threads, you may not see any change in output order by setting your thread priorities. If there is a free CPU then even a lower priority thread will be scheduled to run.
Also, threads are never starved. Even a lower priority thread will given time to run quite often in such a situation as this. You should see higher priority threads be given time sliced to run more often but it does not mean lower priority threads will wait for them to finish before running themselves.
Even if priorities do help to give one thread more CPU than the others, threaded programs are subject to race conditions which help inject a large amount of randomness to their execution. What you should see however, is the max priority thread is more likely to spit out its 0 message more often than the rest. If you add the priority to the println(), that should become obvious over a number of runs.
It is also important to note that System.out.println(...) is synchronized method that is writing IO which is going to dramatically affect how the threads interact and the different threads are blocking each other. In addition, Thread.yield(); can be a no-op depending on how the OS does its thread scheduling.
but a random result (every time I run it changes):
Right. The output from a threaded program is rarely if ever "perfect" because by definition the threads are running asynchronously. We want the output to be random because we want the threads to be running in parallel independently from each other. That is their power. If you expecting some precise output then you should not be using threads.

Thread priority is implementation dependent. In particular, in Windows:
Thread priority isn't very meaningful when all threads are competing
for CPU. (Source)
The book "Java Concurrency in Practice" also says to
Avoid the temptation to use thread priorities, since they increase
platform dependence and can cause liveness problems. Most concurrent
applications can use the default priority for all threads.

Thread priority does not guarantee execution order. It comes into play when resources are limited. If the System is running into constraints due to memory or CPU, then the higher priority threads will run first. Assuming that you have sufficient system resources (which I would assume so for a simple program and the system resources you posted), then you will not have any system constraints. Here is a blog post (not my post) I found that provides more information about it: Why Thread Priority Rarely Matters.

Let's keep it simple and go straight to the source ...
Every thread has a priority. When there is competition for processing
resources, threads with higher priority are generally executed in
preference to threads with lower priority. Such preference is not,
however, a guarantee that the highest priority thread will always be
running, and thread priorities cannot be used to reliably implement
mutual exclusion.
from the Java Language Specification (2nd Edition) p.445.
Also ...
Although thread priorities exist in Java and many references state
that the JVM will always select one of the highest priority threads
for scheduling [52, 56, 89], this is currently not guaranteed by the
Java language or virtual machine specifications [53, 90]. Priorities
are only hints to the scheduler [127, page 227].
from Testing Concurrent Java Components (PhD Thesis, 2005) p. 62.
Reference 127, page 227 (from the excerpt above) is from Component Software: Beyond Object-Oriented Programming (by C. Szyperski), Addison Wesley, 1998.
In short, do not rely on thread priorities.

Thread priority is only a hint to OS task scheduler. Task scheduler will only try to allocate more resources to a thread with higher priority, however there are no explicit guarantees.
In fact, it is not only relevant to Java or JVM. Most non-real time OS use thread priorities (managed or unmanaged) only in a suggestive manner.
Jeff Atwood has a good post on the topic: "Thread Priorities are Evil"
Here's the problem. If somebody begins the work that will make 'cond'
true on a lower priority thread (the producer), and then the timing of
the program is such that the higher priority thread that issues this
spinning (the consumer) gets scheduled, the consumer will starve the
producer completely. This is a classic race. And even though there's
an explicit Sleep in there, issuing it doesn't allow the producer to
be scheduled because it's at a lower priority. The consumer will just
spin forever and unless a free CPU opens up, the producer will never
produce. Oops!

As mentioned in other answers, Thread priority is more a hint than a definition of a strict rule.
That said, even if priority would be considered in a strict(er) way, your test-setup would not lead to the result which you describe as "expected". You are first creating 5 threads having equally low priority and one thread having high priority.
The CPU you are using (i3) has 4 native threads. So even if high priory would imply that the thread runs without interruption (which is not true), the low priority threads will get 3/4 of the cpu power (given that no other task is running). This CPU power is allocated to 5 threads, thus the low priority threads will run at 4 * 3/4 * 1/5 = 3/5 times the speed of the high priority thread. After the high priority thread has completed, the low priority threads run at 4/5 of the speed of the high priority thread.
You are launching the low priority threads before the high priority threads. Hence they start a bit earlier. I expect that in most systems "priority" is not implemented down to the nanosecond. So the OS will allow that a threads runs "a little longer" until it switches to another thread (to reduce the impact of switching cost). Hence, the result depends a lot on how that switching is implemented and how big the task is. If the task is small, it could be that no switching will take place, and in your example all the low priority threads finish first.
These calculations assumed that high and low priority where interpreted as extrem cases. In fact, priority is rather something like "in n out of m cases prefer this" with variable n and m.
You have a Thread.yield in your code! This will pass execution to another thread. If you do that too often, it will result in all threads getting equal CPU power.
Hence, I would not expect the output you mentioned in your question, namely that the high priority thread finishes first and then the low priority thread finish.
Indeed: With the line Thread.yield I have the result that each thread get the same CPU time. Without the line Thread.yield and increasing the number of calculations by a factor of 10 and increasing the number of low prio threads by a factor of 10, I get an expected result, namely that the high prio thread finishes earlier by some factor (which depends on the number of native CPU threads).

I believe the OS is free to disregard Java thread priority.

Thread priority is a hint (which can be ignored) such that when you have 100% CPU, the OS know you want to prefer some threads over others. The thread priority must be set before the thread is started or it can be ignored.
On Windows you have to be Administrator to set the thread priority.

Several things to consider:
thread priorities are evil and in most cases they should not be used: http://www.codinghorror.com/blog/2006/08/thread-priorities-are-evil.htmll
you explicitely yield, which probably makes your test invalid
have you checked the generated bytecode? Are you certain that your volatile variable is behaving as you expect it to? Reordering may still happen for volatile variables.

Some OS doesn't provide proper support for Thread priorities.

You have got to understand that different OS deal with thread priorities differently. For example Windows uses a pre-emptive time-slice based scheduler which gives a bigger time slice to higher priority threads where as some other OS (very old ones) use non pre-emptive scheduler where higher priority thread is executed entirely before lower priority thread unless the higher priority thread goes to sleep or does some IO operation etc.
That is why it is not guaranteed that the higher priority thread completely executes, it infact executes for more time than low priority threads so that is why your outputs are ordered in such a way.
In order to know how Windows handles multithreading please refer the below link:
https://learn.microsoft.com/en-us/windows/win32/procthread/multitasking

High-priority thread doesn't stop low-priority thread until it's done. High-priority doesn't make something faster either, if it did, we'd always make everything high-priority. And low-priority doesn't make things slower or we'd never use it.
As I understand you are misunderstanding that rest of the system should be idle and just let the highest-priority thread work while the rest of the system's capacity is wasted.

Related

How long does it take to change a thread's priority in Java?

What I can't find is any statement on whether changing a thread's priority is a costly operation, time-wise. I would like to do it frequently, but if each switch carries a significant time penalty it is probably not worth the trouble.
What I can't find is any statement on whether changing a thread's priority is a costly operation, time-wise. I would like to do it frequently, but if each switch carries a significant time penalty it is probably not worth the trouble.
Any answer here is going to be very OS dependent. I suspect with most Unix variants that the answer is no, it's not costly. It may require some sort of data synchronization but otherwise it is just setting a value on the thread's administrative information. I suspect that there is no rescheduling of the threads as discussed in the comments.
That said, without knowing more about your particular use case, I doubt it is going to be worth the trouble. As I say in the answer listed below, about the only time thread prioritization will make a difference is if all of the threads are completely CPU bound and you want one task or another to get more cycles.
Also, thread priorities are very non-linear and small changes to them may have little to no effect so any overhead incurred in setting the thread priorities will overwhelm any benefits gained by changing them.
See my answer here:
Guide for working with Linux thread priorities and scheduling policies?
Also, check out this article about Java thread priorities and some real life testing of them under Linux. To quote:
As can be seen, thread priorities 1-8 end up with a practically equal share of the CPU, whilst priorities 9 and 10 get a vastly greater share (though with essentially no difference between 9 and 10). The version tested was Java 6 Update 10.
In the case of Windows, a call to SetThreadPriority to change the priority of a ready to run thread is a system call that will move the thread from it's current priority ready queue to a different priority ready queue, which is more costly than just setting some value in a thread object.
If SetThreadPriority is used to increase the priority of a thread, and if that results in the now higher priority thread preempting a lower priority thread, the preemption occurs at call time, not at the next time slice.
Ready queues are mentioned here:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms682105(v=vs.85).aspx
Context switching related to a priority change is mentioned here: "The following events might require thread dispatching ... A thread’s priority changes, either because of a system service call or because Windows itself changes the priority value." and "Preemption ... a lower-priority thread is preempted when a higher-priority thread becomes ready to run. This situation might occur for a couple of reasons: A higher-priority thread’s wait completes ... A thread priority is increased or decreased." Ready queues are also mentioned: "Windows multiprocessor systems have per-processor dispatcher ready queues"
https://www.microsoftpressstore.com/articles/article.aspx?p=2233328&seqNum=7
I asked about this at MSDN forums. The fourth post agrees with the sequence I mention in the first and third post in this thread:
https://social.msdn.microsoft.com/Forums/en-US/d4d40f9b-bfc9-439f-8a76-71cc5392669f/setthreadpriority-to-higher-priority-is-context-switch-immediate?forum=windowsgeneraldevelopmentissues
In the case of current versions of Linux, run queues indexed by priority were replaced by a red-black tree. Changing a thread's priority would involve removal and reinsertion of a thread object within the red-black tree. Preemption would occur if the thread object is moved sufficiently to the "left" of the red-black tree.
https://www.ibm.com/developerworks/library/l-completely-fair-scheduler
In response to the comments about the app that "examines a full-speed stream of incoming Bluetooth data packets", the receiving thread should be highest priority, hopefully spending most of its time not running while waiting for the reception of a packet. The high priority packets would be queued up to be processed by another thread just lower in priority than the receiving thread. Multiple processing threads could take advantage of multiple cores if needed.

Difference between thread priorities

What does thread priority means? will a thread with MAX_PRIORITY completes its execution before a thread which has MIN_PRIORITY? Or a MAX_PRIORITY thread will be given more execution time then MIN_PRIORITY thread? or any thing else?
The javadoc for Thread only says this, "Threads with higher priority are executed in preference to threads with lower priority." That can mean different things depending on what JVM you are running and, more likely, on what operating system you are running.
In the simplest interpretation of "priority", as implemented by some real-time, embedded operating systems; a thread with a lower priority will never get to run when a higher priority thread is waiting to run. The lower priority thread will be immediately preempted by whatever event caused the higher priority thread to become runnable. That kind of absolute priority is easy to implement, but it puts a burden on the programmer to correctly assign priorities to all of the different threads of all of the different processes running in the box. That is why you usually don't see it outside of embedded systems.
Most general-purpose operating systems assume that not all processes are designed to cooperate with one another. They try to be fair, giving an equal share to each thread that wants CPU time. Usually that is accomplished by continually adjusting the thread's true priorities according to some formula that accounts for how much CPU different threads have wanted in the recent past, and how much each got. There usually is some kind of a weighting factor, to let a programmer say that this thread should get a larger "share" than that thread. (e.g., the "nice" value on a Unix-like system.)
Because any practical JVM must rely on the OS to provide thread scheduling, and because there are so many different ways to interpret"priority"; Java does not attempt to dictate what "priority" really means.

Thread Priority for more than 10 Threads in JAVA

I know that Threads can have Priority ranging from MIN_PRIORITY(1) to MAX_PRIORITY(10). However, if I have more than 10 threads to execute, how will I assign priority to them ? Can the priority be more than 10 ?
However, if I have more than 10 threads to execute, how will I assign [a different] priority to [each of] them ?
You can't.
But it should not matter. The chances are that thread priorities will only give you a rough prioritization anyway. Certainly, the javadocs do not give any strong guarantees about how (or even if) thread priorities affect thread scheduling.
The actual implementation of thread scheduling and thread priorities on a modern JVM is done by the operating system's thread scheduler. Java Thread priorities are really little more than a "hint" to the operating system.
The bottom line is that an Java application that relies on thread priorities for correct behaviour is likely to be unreliable, and to behave differently / incorrectly if run on a different platform to the one you originally developed / debugged for. You should never rely on priorities for correct behaviour. Use the synchronization primitives provided to ensure that things occur in the required order.
If you need precise behaviour of thread priorities, you will need to use a "real-time Java" JVM running on top of a "real-time operating system".
The javadoc states the following about setPriority(int)
Throws:
IllegalArgumentException - If the priority is not in the range
MIN_PRIORITY to MAX_PRIORITY.
Depending on the implementation, you'll need to specify an appropriate value. You won't be able to have a finer priority setting with Thread.
no u can't assign priority which is above 10 since u wil be having a max priority is 10 and min priority is 1 ..even though if u assign with priority above 10 it can be treated as a default priority and the program starts to work according to that priority.

Prioritization of threads within threads

Suppose you have a program that starts two threads a and b, and b starts another ten threads of its own. Does a receive half of the available "attention" while b and its threads share the other half, or do they all share equally? If the answer is the latter by default, how could you achieve the former? Thanks!
There are lots of nice documentation on this topic. One such is this.
When a Java thread is created, it inherits its priority from the thread that created it. You can also modify a thread's priority at any time after its creation using the setPriority() method. Thread priorities are integers ranging between MIN_PRIORITY and MAX_PRIORITY (constants defined in the Thread class). The higher the integer, the higher the priority. At any given time, when multiple threads are ready to be executed, the runtime system chooses the "Runnable" thread with the highest priority for execution. Only when that thread stops, yields, or becomes "Not Runnable" for some reason will a lower priority thread start executing. If two threads of the same priority are waiting for the CPU, the scheduler chooses one of them to run in a round-robin fashion. The chosen thread will run until one of the following conditions is true:
A higher priority thread becomes "Runnable".
It yields, or its run() method exits.
On systems that support time-slicing, its time allotment has expired.
At any given time, the highest priority thread is running. However, this is not guaranteed. The thread scheduler may choose to run a lower priority thread to avoid starvation. For this reason, use priority only to affect scheduling policy for efficiency purposes. Do not rely on thread priority for algorithm correctness.
Does a receive half of the available "attention" while b and its threads share the other half, or do they all share equally?
Neither. The proportion of time received by each thread is unspecified, and there's no reliable way to control it in Java. It is up to the native thread scheduler.
If the answer is the latter by default, how could you achieve the former?
You can't, reliably.
The only thing that you have to influence the relative amounts of time each thread gets to run are thread priorities. Even they are not reliable or predictable. The javadocs simply say that a high priority thread is executed "in preference to" a lower priority thread. In practice, it depends on how the native thread scheduler handles priorities.
For more details: http://docs.oracle.com/javase/7/docs/technotes/guides/vm/thread-priorities.html ... which includes information on how thread priorities on a range of platforms and Java versions.
One cannot say with surity the order in which the threads will be executed. Thread Scheduler works as per its inbuilt algorithm which we cannot change. Thread Scheduler picks up any threads (Highest priority threads) from runnable pool and make it running.
We can only mention the priority in which scheduler should process our threads.

Recursively adding threads to a Java thread pool

I am working on a tutorial for my Java concurrency course. The objective is to use thread pools to compute prime numbers in parallel.
The design is based on the Sieve of Eratosthenes. It has an array of n bools, where n is the largest integer you are checking, and each element in the array represents one integer. True is prime, false is non prime, and the array is initially all true.
A thread pool is used with a fixed number of threads (we are supposed to experiment with the number of threads in the pool and observe the performance).
A thread is given a integer multiple to process. The thread then finds the first true element in the array that is not a multiple of thread's integer. The thread then creates a new thread on the thread pool which is given the found number.
After a new thread is formed, the existing thread then continues to set all multiples of it's integer in the array to false.
The main program thread starts the first thread with the integer '2', and then waits for all spawned threads to finish. It then spits out the prime numbers and the time taken to compute.
The issue I have is that the more threads there are in the thread pool, the slower it takes with 1 thread being the fastest. It should be getting faster not slower!
All the stuff on the internet about Java thread pools create n worker threads the main thread then wait for all threads to finish. The method I use is recursive as a worker can spawn more worker threads.
I would like to know what is going wrong, and if Java thread pools can be used recursively.
Your solution may run slower as threads are added for some of following problems:
Thread creation overheads: creating a thread is expensive.
Processor contention: if there are more threads than there are processors to execute them, some of threads will be suspended waiting for a free processor. The result is that the average processing rate for each thread drops. Also, the OS then needs to time-slice the threads, and that takes away time that would otherwise be used for "real" work.
Virtual memory contention: each thread needs memory for its stack. If your machine doesn't have enough physical memory for the workload, each new thread stack increases virtual memory contention which results in paging which slows things down
Cache contention: each thread will (presumably) be scanning a different section of the array, resulting in memory cache misses. This slows down memory accesses.
Lock contention: if your threads are all reading and updating a shared array and using synchronized and one lock object to control access to the array, you could be suffering from lock contention. If a single lock object is used, each thread will spend most of its time waiting to acquire the lock. The net result is that the computation is effectively serialized, and the overall processing rate drops to the rate of a single processor / thread.
The first four problems are inherent to multi-threading, and there are no real solutions ... apart from not creating too many threads and reusing the ones that you have already created. However, there are a number of ways to attack the lock contention problem. For example,
Recode the application so that each thread scans for multiple integers, but in its own section of the array. This will eliminate lock contention on the arrays, though you will then need a way to tell each thread what to do, and that needs to be designed with contention in mind.
Create an array of locks for different regions of the array, and have the threads pick the lock to used based on the region of the array they are operating on. You would still get contention, but on average you should get less contention.
Design and implement a lockless solution. This would entail DEEP UNDERSTANDING of the Java memory model. And it would be very difficult to prove / demonstrate that a lockless solution does not contain subtle concurrency flaws.
Finally, recursive creation of threads is probably a mistake, since it will make it harder to implement thread reuse and the anti-lock-contention measures.
How many processors are available on your system? If #threads > #processors, adding more threads is going to slow things down for a compute-bound task like this.
Remember no matter how many threads you start, they're still all sharing the same CPU(s). The more time the CPU spends switching between threads, the less time it can be doing actual work.
Also note that the cost of starting a thread is significant compared to the cost of checking a prime - you can probably do hundreds or thousands of multiplications in the time it takes to fire up 1 thread.
The key point of a thread pool is to keep a set of thread alive and re-use them to process tasks. Usually the pattern is to have a queue of tasks and randomly pick one thread from the pool to process it. If there is no free thread and the pool is full, just wait.
The problem you designed is not a good one to be solved by a thread pool, because you need threads to run in order. Correct me if I'm wrong here.
thread #1: set 2's multiple to false
thread #2: find 3, set 3's multiple to false
thread #3: find 5, set 5's multiple to false
thread #4: find 7, set 7's multiple to false
....
These threads need to be run in order and they're interleaving (how the runtime schedules them) matters.
For example, if thread #3 starts running before thread #1 sets "4" to false, it will find "4" and continue to reset 4's multiples. This ends up doing a lot of extra work, although the final result will be correct.
Restructure your program to create a fixed ThreadPoolExecutor in advance. Make sure you call ThreadPoolExecutor#prestartAllCoreThreads(). Have your main method submit a task for the integer 2. Each task will submit another task. Since you are using a thread pool, you won't be creating and terminating a bunch of threads, but instead allowing the same threads to take on new tasks as they become available. This will reduce on overall execution overhead.
You should discover that in this case the optimum number of threads is equal to the number of processors (P) on the machine. It is often the case that the optimum number of threads is P+1. This is because P+1 minimizes overhead from context switching while also minimizing loss from idle/blocking time.

Categories