Java multithreading - thread priority - java

Can anybody explain how thread priority works in java. The confusion here is if java does'nt guarantee the implementation of the Thread according to its priority then why is this setpriority() function used for.
My code is as follows :
public class ThreadSynchronization implements Runnable{
public synchronized void run() {
System.out.println("Starting Implementation of Thread "+Thread.currentThread().getName());
for(int i=0;i<10;i++)
{
System.out.println("Thread "+Thread.currentThread().getName()+" value : "+i);
}
System.out.println("Ending Implementation of Thread "+Thread.currentThread().getName());
}
public static void main(String[] args) {
System.out.println("Program starts...");
ThreadSynchronization th1 = new ThreadSynchronization();
Thread t1 = new Thread(th1);
t1.setPriority(1);
synchronized(t1)
{
t1.start();
}
ThreadSynchronization th2 = new ThreadSynchronization();
Thread t2 = new Thread(th2);
t2.setPriority(9);
synchronized (t2) {
t2.start();
}
System.out.println("Program ends...");
}
}
In the above program even if I change the priority I find no difference in the output.
Also a real time application of how thread priority can be used would be of great help.
Thanks.

Thread priority is just a hint to OS task scheduler and is dependent on the underlying OS. OS will try to allocate more resources to a high priority thread but it does not guarantee it. So if your program is dependent on thread priorities than you are in-turn binding your program to underlying OS, which is bad.
From Java Concurrency in Practice:
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 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.
Also very important, Priorties are different to every underlying plattform. Therefore you kind of loose your plattform freedom of java. See this summary as well:
Indeed, some priority levels can map to the same "native" priority level. Here's the list (based on the Hotspot code in OpenJDK 6):
Solaris
1 ⇒ 0
2 ⇒ 32
3 ⇒ 64
4 ⇒ 96
5 – 10 ⇒ 127
Of note is that on Solaris, you can't raise the thread priority above normal, only lower it: the priority value for 5 is the same as any of the higher values.
Linux
1 – 10 ⇒ 4 – -5 (nice values)
Of note is that on Linux, different thread priorities in Java do map to distinct priority values at native level.
Windows
1 – 2 ⇒ THREAD_PRIORITY_LOWEST
3 – 4 ⇒ THREAD_PRIORITY_BELOW_NORMAL
5 – 6 ⇒ THREAD_PRIORITY_NORMAL
7 – 8 ⇒ THREAD_PRIORITY_ABOVE_NORMAL
9 – 10 ⇒ THREAD_PRIORITY_HIGHEST
I've developed a lot of multi threaded java applications, and in my opinion if you have to set thead priorities you have another problem. Like a bad algorythm that consumes to much cpu time etc.... I always suggest to not change the java thread prio, since you can't rely on it anyways. (of course there are some scenarios where it makes sense)

There are several situations where setting a priority for a Thread is useful, you just must not start believing in any guarantees that come form such settings, as always: the order of execution with threads is undefined. If you think that your thread will be done earlier if you give it a higher priority, please read the statement above again until that's out of your head. ;)
You should define the priority based on how important it is for this thread to gain execution time compared to the others. Even though the underlaying system guarantees nothing, it still can provide a benefit for those JVMs that support it.
Example: You have a program that does some heavy calculation based on user input in your JFrame. It is a good practice to set those background threads to a low priority, because it is more important that the JFrame is responsive than working on the calculation (which will take a long time to finish anyways, a few more millis won't hurt). The OS will still assign most CPU time to the low priority threads, unless something more important needs it. But then it is good that this more important stuff gets the priority.
Now it could happen that on some systems the priority setting is ignored and the JFrame is again unresponsive, but then this does nothing worse to your code then not setting the priority to low in the first place.

The size of the tasks is too small and probably will complete right after the start. Also, if you have "enough" CPU cores, each worker thread will be allocated to one core, so the result will be the same.
Try the experiment in a different context, first increase the task size (for example by looping one thousand times to one million, without print) then increase the number of threads to exceed the number of cores you have and third, create your threads first and then start all the threads (you cannot start them at once, you will still need to loop through them).
In my case, I have chosen 10 threads because I ran the code on a processor with two hyper-threaded cores, running four simultaneous threads.
My changes to your example:
public class ThreadPriority implements Runnable {
public synchronized void run() {
System.out.println("Starting Implementation of Thread " + Thread.currentThread().getName());
float s = 0;
for (int i = 0; i < 1000; i++)
for (int k = 0; k < 1000000; k++)
s += k;
System.out.println("Ending Implementation of Thread " + Thread.currentThread().getName() + " " + s);
}
Thread t;
public ThreadPriority(String name, int prio) {
t = new Thread(this);
t.setName(name);
t.setPriority(prio);
}
public void start() {
synchronized (t) {
t.start();
}
}
public static void main(String[] args) {
System.out.println("Program starts...");
ThreadPriority[] th = new ThreadPriority[10];
for (int i = 0; i < th.length; i++) {
th[i] = new ThreadPriority("T" + i, i / 2 + 1);
}
for (ThreadPriority tp : th)
tp.start();
System.out.println("Program ending, wait for all the threads to complete");
}
}
Results are:
Program starts...
Starting Implementation of Thread T0
Starting Implementation of Thread T9
Starting Implementation of Thread T8
Starting Implementation of Thread T5
Program ending, wait for all the threads to complete
Starting Implementation of Thread T4
Starting Implementation of Thread T6
Starting Implementation of Thread T7
Starting Implementation of Thread T2
Starting Implementation of Thread T3
Starting Implementation of Thread T1
Ending Implementation of Thread T6 1.7592186E13
Ending Implementation of Thread T7 1.7592186E13
Ending Implementation of Thread T4 1.7592186E13
Ending Implementation of Thread T8 1.7592186E13
Ending Implementation of Thread T9 1.7592186E13
Ending Implementation of Thread T5 1.7592186E13
Ending Implementation of Thread T2 1.7592186E13
Ending Implementation of Thread T0 1.7592186E13
Ending Implementation of Thread T1 1.7592186E13
Ending Implementation of Thread T3 1.7592186E13
As you can see, the low number threads tend to end later, because the high number threads have higher priority. By turning the scale upside down:
for (int i = 0; i < th.length; i++) {
th[i] = new ThreadPriority("T" + i, 9 - i / 2 );
}
The low number threads complete faster than the high ones. Some threads complete even before other threads are started, because they have higher priority compared to the calling program:
Program starts...
Starting Implementation of Thread T0
Starting Implementation of Thread T1
Starting Implementation of Thread T2
Starting Implementation of Thread T3
Program ending, wait for all the threads to complete
Ending Implementation of Thread T2 1.7592186E13
Ending Implementation of Thread T3 1.7592186E13
Ending Implementation of Thread T0 1.7592186E13
Ending Implementation of Thread T1 1.7592186E13
Starting Implementation of Thread T9
Starting Implementation of Thread T4
Starting Implementation of Thread T8
Starting Implementation of Thread T7
Starting Implementation of Thread T5
Starting Implementation of Thread T6
Ending Implementation of Thread T4 1.7592186E13
Ending Implementation of Thread T5 1.7592186E13
Ending Implementation of Thread T7 1.7592186E13
Ending Implementation of Thread T8 1.7592186E13
Ending Implementation of Thread T9 1.7592186E13
Ending Implementation of Thread T6 1.7592186E13

Hope it helps!
package priority;
public class ThreadPriorityApp {
// Note : Thread priority may not be supported in some OS due to underlying task scheduler at OS level
/**
* MyThread is an inner class implementing Thread functionality
*
*/
class MyThread extends Thread {
public MyThread(String threadName) {
super(threadName);
}
public void run() {
System.out.println("Running thread - " + Thread.currentThread().getName());
}
}
public static void main(String[] args) {
//If priority is not set then main priority is set to threads created inside main thread - Parent to child
// Main thread priority - 5, is set to Thread 1 and Thread 2, if not manually assigned (commenting Line #34 and #35)
System.out.println("Main thread priority - " + Thread.currentThread().getPriority());
ThreadPriorityApp threadPriorityApp = new ThreadPriorityApp();
//We are creating two threads
MyThread th = threadPriorityApp.new MyThread("Thread 1");
MyThread th2 = threadPriorityApp.new MyThread("Thread 2");
// Range 1 to 10 - 10 being given as MAX Priority
th.setPriority(Thread.MIN_PRIORITY);
th2.setPriority(Thread.MAX_PRIORITY);
//We have started Thread 1 first and then Thread 2 later
th.start();
th2.start();
// Possible Outcomes(1) (With Priority - Line #34 and #35) :
// Running thread - Thread 2
// Running thread - Thread 1
// Possible Outputs(2) : (Without Priority - commenting Line #34 and #35)
// (1) Running thread - Thread 1
// Running thread - Thread 2
// OR
// (2) Running thread - Thread 2
// Running thread - Thread 1
}
//Happy coding -- Parthasarathy S
}

//The iterative and recursive with memorize both shows count as 1424 for digits of length ten starting with 1.
int[][] b = {{4,6},{6,8},{7,9},{4,8},{0,3,9},{},{1,7,0},{2,6},{1,3},{2,4}};
public int countIterative(int digit, int length) {
int[][] matrix = new int[length][10];
for(int dig =0; dig <=9; dig++){
matrix[0][dig] = 1;
}
for(int len = 1; len < length; len++){
for(int dig =0; dig <=9; dig++){
int sum = 0;
for(int i : b[dig]){
sum += matrix[len-1][i];
}
matrix[len][dig] = sum;
}
}
return matrix[length-1][digit];
}
public int count(int index, int length, int[][] matrix ){
int sum = 0;
if(matrix[length-1][index] > 0){
return matrix[length-1][index];
}
if( length == 1){
return 1;
}
for(int i: b[index] ) {
sum += count(i, length-1,matrix);
}
matrix[length-1][index] = sum;
return sum;
}

Related

Java thread output

public class oneThread extends Thread {
public void run()
{
System.out.println("geeks ");
try {
Thread.sleep(300);
}
catch (InterruptedException ie) {
}
System.out.println("forgeeks ");
}
public static void main(String[] args)
{
oneThread c1 = new oneThread();
oneThread c2 = new oneThread();
c1.start();
c2.start();
System.out.println(c1.isAlive());
System.out.println(c2.isAlive());
}
}
its real output is ->
geeks
true
true
geeks
forgeeks
forgeeks
how is this correct ?
I expected it to be ->
geeks
geeks
true
true
forgeeks
forgeeks
There are lots of legal execution sequences that could give rise to that output.
For example:
in main: c1.start()
in main: c2.start()
in thread 1: println("geeks")
in thread 1: sleep
in main: println(c1.isAlive()); println(c2.isAlive());
in thread 2: println("geeks")
in thread 2: sleep
in thread 1: println("for geeks")
in thread 2: println("for geeks")
JVM terminates since all threads have completed
Other possible execution sequences include:
Steps 3 and 4 could happen before step 2.
Thread 2 could be scheduled before thread 1.
Thread 2 could "overtake" thread 1 due to the sleep times being imprecise.
And so on.
These are all legal behaviors, and on some platforms you might actually encounter them.
This is perfectly valid behavior. The JVM is free to decide which Thread runs and when. Some of the things you should note is that starting a thread takes some time, and while Thread 2 is still starting, main keeps going and gets to its print. Also Threads can be put to sleep for a lengthy IO operation such as System.out.println, and another thread will run while the print is executing.

Multithreading start method

and this a normal thread program
class Counter implements Runnable {
private int currentValue;
public Counter() { currentValue = 0; }
public int getValue() { return currentValue; }
public void run() { // (1) Thread entry point
try {
while (currentValue < 5) {
System.out.println(Thread.currentThread().getName() + ": " + (currentValue++)); // (2) Print thread name.
Thread.sleep(250); // (3) Current thread sleeps.
}
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName() + " interrupted.");
}
System.out.println("Exit from thread: " + Thread.currentThread().getName());
}
}
//_______________________________________________________________________________
public class Client {
public static void main(String[] args) {
Counter counterA = new Counter(); // (4) Create a counter.
Thread worker = new Thread(counterA, "Counter A");// (5) Create a new thread.
System.out.println(worker);
worker.start(); // (6) Start the thread.
try {
int val;
do {
val = counterA.getValue(); // (7) Access the counter value.
System.out.println("Counter value read by " + Thread.currentThread().getName()+ ": " + val); // (8) Print thread name.
Thread.sleep(1000); // (9) Current thread sleeps.
} while (val < 5);
} catch (InterruptedException e) {
System.out.println("The main thread is interrupted.");
}
System.out.println("Exit from main() method.");
}
}
and the output is
Thread[Counter A,5,main]
Counter value read by main thread: 0
Counter A: 0
Counter A: 1
Counter A: 2
Counter A: 3
Counter value read by main thread: 4
Counter A: 4
Exit from thread: Counter A
Counter value read by main thread: 5
Exit from main() method.
My question is even though the worker thread was started initially before the Main thread enters it's try block, Main thread execution starts first and then when the Main thread goes to sleep child thread gets into action.
As this picture(taken from "A Programmer's Guide To Java SCJP Certification : A Comprehensive Primer 3rd Edition"
Author: Khalid A Mughal, Rolf W Rasmussen) depicts that when the start method is called on the thread it returns immediately.
Please explain this point that why on invoking start method it return immediately and does the thread get starts on calling the start method. As here on calling the start method it doesn't invoke run method of the class. So when does actually the thread starts ?
Also explain this " the call to the start() method is asynchronous."
there are three things that you are missing in your overall analysis.
Call to thread's start method is sequential not parallel. Its the call to run method of Thread that is concurrent. So if you have 5 statements in main method that call start, the 5ht is not going t be called first. Thats the 'happens before' guarantee that JVM specs give you. However the run method of 1 first may get called before or after the call to the second start statement. This depends as its more of a CPU time slicing issue rather than program execution.
When more than 1 thread runs in your program the order of output is in-deterministic. That's because they run in parallel. You can never be sure that the same program will run in same order on two machines or even in two runs on the same machine. In your question you have posted only 1 output. Run the program like 20 times one after another and match the output. I am sure 2 or 3 would be entirely different.
Finally, you are basing your analysis on the order or execution of your concurrent code. That's the biggest blooper programmer make. Concurrent programs are never intended to run in a specific order or sequence. Just try to make your Runnable work an atomic mutually exclusive task (mutually exclusive to the rest of program or even to other Runnables) and track its own execution. Dont mix Threads together.
You cannot directly enforce which Thread is executed/running when. Once you start it, it's handled on lower level(usually by OS) and the results may differ on different machine or even in different execution. If you need more control, you need to use some synchronization mechanism.
The thread is isn't started synchronously underneath the call to start(). It happens later (asynchronously). In other words, just because you called start() doesn't mean the thread has started.
They why and how are all implementation details, that may depend on JVM and/or OS implementations.

when does the main thread die?

The question was to generate random numbers between 1 and 99 using a thread. However the problem here is I don't know where does the "main thread is stopping" coming from?
Doesn't the main thread die in the end?
This is the sample output:
Main thread stopping
Random no = 57
Random no = 47
Random no = 96
Random no = 25
Random no = 74
Random no = 15
Random no = 46
Random no = 90
Random no = 52
Random no = 97
Thread that generates random nos is stopping
Mythread class:
public class MyThread extends Thread {
MyThread() {
// default constructor
}
MyThread(String threadName) {
super(threadName); // Initialize thread.
start();
}
public void run() {
// System.out.println(Thread.currentThread().getName());
Random rand = new Random();
int newValue;
for (int i = 0; i < 10; i++) {
newValue = rand.nextInt(99);// generates any vale between 1 to 99
System.out.println("Random no = " + newValue);
}
System.out.println("Thread that generates random nos is stopping");
}
}
Main class:
public class HW5ex2a {
public static void main(String[] args) throws InterruptedException {
MyThread t = new MyThread();
t.start();
t.join();// wait for the thread t to die
System.out.println("Main thread stopping");
}
}
You can't rely on the order that main thread and other threads write to System.out.
Your thread t executes fine, the main thread waits for it to finish and then the main thread exits, all as expected. But this isn't reflected in the order that you see on System.out.
To directly answer your question - the main thread waits for the thread to finish, then it writes a message to System.out, then it dies. The only confusing thing is that, because you are writing to System.out from two different threads, you don't have any guarantees about the relative ordering. Println's from the two different threads could show up interleaved in any way...it just happens to show up with the output from the main thread first.
As Alexis Leclerc points out - you get an unpredictable interleaving, the same as in this java threads tutorial.
Memory Synchronization in a Multi-core System
Since both threads are being run on separate cores (most probably), the objects that the threads have access to are cached by each core (in L1 cache) for improved performance.
Whenever the state of the object is changed, all caches try to synchronize with value in RAM, which is not guarantied to occur immediately.
Some threads might be able to synchronize before other threads even if it violates happens-before relationship between them.
The reason behind this lies in the implementation of the java memory model.
The same thing is happening with System.out object here.
You can not guaranty the order in which the data is passed and flushed through it.
Therefore it is unpredictable. Calling
System.out.flush();
might improve the result, but it will not guaranty.
For more, refer to Multiple threads using System.out.println in Java
Hope this helps.
The main thread exit on below situation :-
Normally when program execution complete .
If you are using System.exit(1).
JVM crashes.
Hope it will help you.

Fibonacci on Java ExecutorService runs faster sequentially than in parallel

I am trying out the executor service in Java, and wrote the following code to run Fibonacci (yes, the massively recursive version, just to stress out the executor service).
Surprisingly, it will run faster if I set the nThreads to 1. It might be related to the fact that the size of each "task" submitted to the executor service is really small. But still it must be the same number also if I set nThreads to 1.
To see if the access to the shared Atomic variables can cause this issue, I commented out the three lines with the comment "see text", and looked at the system monitor to see how long the execution takes. But the results are the same.
Any idea why this is happening?
BTW, I wanted to compare it with the similar implementation with Fork/Join. It turns out to be way slower than the F/J implementation.
public class MainSimpler {
static int N=35;
static AtomicInteger result = new AtomicInteger(0), pendingTasks = new AtomicInteger(1);
static ExecutorService executor;
public static void main(String[] args) {
int nThreads=2;
System.out.println("Number of threads = "+nThreads);
executor = Executors.newFixedThreadPool(nThreads);
Executable.inQueue = new AtomicInteger(nThreads);
long before = System.currentTimeMillis();
System.out.println("Fibonacci "+N+" is ... ");
executor.submit(new FibSimpler(N));
waitToFinish();
System.out.println(result.get());
long after = System.currentTimeMillis();
System.out.println("Duration: " + (after - before) + " milliseconds\n");
}
private static void waitToFinish() {
while (0 < pendingTasks.get()){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
executor.shutdown();
}
}
class FibSimpler implements Runnable {
int N;
FibSimpler (int n) { N=n; }
#Override
public void run() {
compute();
MainSimpler.pendingTasks.decrementAndGet(); // see text
}
void compute() {
int n = N;
if (n <= 1) {
MainSimpler.result.addAndGet(n); // see text
return;
}
MainSimpler.executor.submit(new FibSimpler(n-1));
MainSimpler.pendingTasks.incrementAndGet(); // see text
N = n-2;
compute(); // similar to the F/J counterpart
}
}
Runtime (approximately):
1 thread : 11 seconds
2 threads: 19 seconds
4 threads: 19 seconds
Update:
I notice that even if I use one thread inside the executor service, the whole program will use all four cores of my machine (each core around 80% usage on average). This could explain why using more threads inside the executor service slows down the whole process, but now, why does this program use 4 cores if only one thread is active inside the executor service??
It might be related to the fact that the size of each "task" submitted
to the executor service is really small.
This is certainly the case and as a result you are mainly measuring the overhead of context switching. When n == 1, there is no context switching and thus the performance is better.
But still it must be the same number also if I set nThreads to 1.
I'm guessing you meant 'to higher than 1' here.
You are running into the problem of heavy lock contention. When you have multiple threads, the lock on the result is contended all the time. Threads have to wait for each other before they can update the result and that slows them down. When there is only a single thread, the JVM probably detects that and performs lock elision, meaning it doesn't actually perform any locking at all.
You may get better performance if you don't divide the problem into N tasks, but rather divide it into N/nThreads tasks, which can be handled simultaneously by the threads (assuming you choose nThreads to be at most the number of physical cores/threads available). Each thread then does its own work, calculating its own total and only adding that to a grand total when the thread is done. Even then, for fib(35) I expect the costs of thread management to outweigh the benefits. Perhaps try fib(1000).

Java - Count in COUNTDOWNLATCH

While running each thread why does the countdown.getCount() always print '3' even after the previous thread has already called countdown.countDown() and reduced the Latch Count by 1?
I am kind of worndering how Java knows that the Latch Count has reached 0, so that it can release all the 3 threads.
import java.util.concurrent.CountDownLatch;
class b {
static final CountDownLatch countdown = new CountDownLatch(3);
public static void main(String[] args) {
for (int i = 0; i < 3; ++i) {
Thread t = new Thread() {
public void run() {
System.out.printf("Starting on %d other threads.\n",
countdown.getCount());
countdown.countDown();
System.out.printf("new on %d other threads.\n",
countdown.getCount());
try {
countdown.await(); // waits until everyone reaches this
// point
// System.out.println("Go again : "
// +countdown.getCount());
} catch (Exception e) {
}
}
};
t.start();
}
System.out.println("Go");
}
}
you are starting 3 threads in parallel. depending on how fast they start, they could all print "3" before any of the threads manages to call countDown() (at least for the "Starting on..." line). the "new on ..." line, however, should print out some range of numbers between 2 and 0.
It's absolutely possible that all three threads print "Starting on 3.." as the threads run in parallel, and the count doesn't change until a thread executed countDown(). To really understand what's going on, I suggest you prepend System.nanoTime() and thread name before your print statements as below:
...
Thread t = new Thread("Thread-" + i) {
...
System.out.printf("%d> %s: Starting on %d other threads.\n", System.nanoTime(), getName(), countdown.getCount());
countdown.countDown();
System.out.printf("%d> %s: new on %d other threads.\n", System.nanoTime(), getName(), countdown.getCount());
Sometimes you'd get an output like below which may give you the impression that Thread-2 is disregarding Thread-1's call to countDown:
1407489646569321000> Thread-0: Starting on 3 other threads.
1407489646569324000> Thread-1: Starting on 3 other threads.
1407489646602463000> Thread-1: new on 1 other threads.
1407489646569513000> Thread-2: Starting on 3 other threads.
1407489646602107000> Thread-0: new on 2 other threads.
1407489646603275000> Thread-2: new on 0 other threads.
However, that is not the case, and we can verify the correct order of operations by looking at the timestamp. The mixup in the output is due to inherent unpredictability in thread scheduling, depending on which thread gets the cpu splice.
Having said that, they may not always print 3, depending on thread scheduling or delays. As an example, try putting a Thread.sleep(..) as shown below:
public static void main(String[] args) throws Exception {
for (int i = 0; i < 3; ++i) {
Thread t = new Thread() {
public void run() {
/* As before */
}
};
t.start();
Thread.sleep(100); // Artificial Delay
}
}
Now you should see different results like below:!
1407490223575404000> Thread-0: Starting on 3 other threads.
1407490223607879000> Thread-0: new on 2 other threads.
1407490223676233000> Thread-1: Starting on 2 other threads.
1407490223676818000> Thread-1: new on 1 other threads.
1407490223777623000> Thread-2: Starting on 1 other threads.
1407490223778221000> Thread-2: new on 0 other threads.
Internally, the CountDownLatch maintains a first in, first out wait Queue (See. AbstractQueuedSynchronizer). The value of the count is synchronized, and the waiting threads are only released when the count becomes 0 or someother thread interrupts the waiting thread. This is the mechanism used by the latch to keep track of when all the threads have arrived at the latch.
If you're interested in understanding the latch in the context of testing, checkout http://razshahriar.com/2014/08/testing-asynchronous-code-in-java-with-countdownlatch/
Hope this helps clarify your investigation of the Program behaviour.

Categories

Resources