My code and output are as below :-
My question is that the priority of main thread and thread t4 is 9 and that of thread t is 5 then why line 1 to 4 (marked in output) is coming before line 5 i.e. why t.start() gets priority over t4.start() which will be executed by main thread which has priority of 9.
Main thread priority is 9 so first t4.start() should get executed but then why t.start() is getting executed first ?
And if I reverse the order of calling start method i.e. if I call in order t4.start() and then t.start() then output is as expected.
Output
5
5
Main Thread Priority :9
5
Calling MyRunnable2 from main....9
Child Class - line 1
Child Class - line 2
End of Child loop - line 3
Calling MyRunnable2 from MyThread - line 4
MyRunnable2 Class....Main....9 - line 5
MyRunnable2 Class....From MyThread run....5
CODE :-
public class ThreadPriority
{
public static void main(String[] args)
{
MyThread t = new MyThread();
System.out.println(Thread.currentThread().getPriority());
System.out.println(t.getPriority());
t.setName("From MyThread");
Thread.currentThread().setPriority(9);
System.out.println("Main Thread Priority :" + Thread.currentThread().getPriority());
System.out.println(t.getPriority());
MyRunnable2 r4 = new MyRunnable2();
Thread t4 = new Thread(r4,"Main");
System.out.println("Calling MyRunnable2 from main"+"...."+t4.getPriority());
t.start();
t4.start();
}
}
class MyRunnable2 implements Runnable
{
public void run()
{
System.out.println("MyRunnable2 Class"+"...."+Thread.currentThread().getName()+"...."+Thread.currentThread().getPriority());
}
}
class MyThread extends Thread
{
public void run()
{
for (int i=0;i<2;i++)
System.out.println("Child Class");
System.out.println("End of Child loop");
MyRunnable2 r2 = new MyRunnable2();
Thread t2 = new Thread(r2,"From MyThread run");
System.out.println("Calling MyRunnable2 from MyThread");
t2.start();
}
t4 priority is higher and its doesn't mean t4 will finish first,Furthermore
jvm ask OS for threads and all priorities sets in deep layer of OS,
you are just set a recommendation,it depends on many things!
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.
Rule of thumb : At any given time, the highest priority thread is running. However, this is not a 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.
I hope the above information clarifies your query.
Related
This question already has answers here:
Java: Thread sequential order
(6 answers)
Closed 2 years ago.
I am trying to figure out the multithreading order using the code below.
I use synchonized to block other threads while one is running in the synchronized part. I was expecting thread 1 should start and end first, then thread 2, finally 3. But the result showed always 1,3,2
So why this happen? Shouldn't be randomly executed like 1 2 3 or 1 3 2?
public class hello {
static class runnablethread extends Thread{
private static int k = 5;
public void run() {
synchronized (runnablethread.class) {
System.out.println(Thread.currentThread().getName() + " start:" + System.currentTimeMillis());
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + " end:" + System.currentTimeMillis());
}
}
public static void main(String[] args) {
runnablethread r1 = new runnablethread();
new Thread(r1,"Thread1").start();
new Thread(r1,"Thread2").start();
new Thread(r1,"Thread3").start();
}
}
Thread1 start:1606114065880
Thread1 end:1606114066885
Thread3 start:1606114066885
Thread3 end:1606114067889
Thread2 start:1606114067889
Thread2 end:1606114068894
The Thread.start() method does not actually call your run method, it just indicates that your thread is ready to be scheduled for execution. The JVM then schedules the execution of the thread, but this scheduling does not guarantee that the order of the scheduling is the same as the order they were started.
In your specific case, the code sequence
new Thread(r1,"Thread1").start();
new Thread(r1,"Thread2").start();
new Thread(r1,"Thread3").start();
is executed quickly and the JVM ends up having 3 threads ready to be scheduled.
If you would want to wait for termination of certain thread, you can use join method.
It is also possible to alter the priority of the thread, using setPriority() method.
If the code is executed more than once, we can notice that the threads are started randomly
$ java hello
Thread1 start:1606124964911
Thread1 end:1606124965915
Thread3 start:1606124965915
Thread3 end:1606124966921
Thread2 start:1606124966921
Thread2 end:1606124967926
$ java hello
Thread1 start:1606124969152
Thread1 end:1606124970155
Thread3 start:1606124970155
Thread2 start:1606124971157
Thread3 end:1606124971157
Thread2 end:1606124972162
$ java hello
Thread1 start:1606124975920
Thread1 end:1606124976925
Thread3 start:1606124976925
Thread3 end:1606124977926
Thread2 start:1606124977926
Thread2 end:1606124978930
$ java hello
Thread2 start:1606124980589
Thread3 start:1606124981592
Thread2 end:1606124981592
Thread3 end:1606124982594
Thread1 start:1606124982594
Thread1 end:1606124983599
I have this Question :
Create and run a thread that writes "Hello friends" on screen. The main Thread waits for it only 500 milliseconds. Then run the program again after you give the created Thread lower priority than the main Thread. This time, the main Thread should wait for it 10 milliseconds. Do you notice anything? Why?
I want to know the difference that made by Thread.setPriority(n)
first code and second get the same output
first code
public class Q2 {
public static void main(String[] args) {
Thread2 myThread = new Thread2();
myThread.start();
System.out.println("main thread");
}
}
class Thread2 extends Thread{
#Override
public void run(){
try {
join(500);
System.out.println("Hello Friends from thread2");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
seconde code
public class Q2 {
public static void main(String[] args) {
Thread2 myThread = new Thread2();
myThread.start();
System.out.println("main thread");
}
}
class Thread2 extends Thread{
#Override
public void run(){
try {
setPriority(MIN_PRIORITY);
join(500);
System.out.println("Hello Friends from thread2");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
the main Thread should wait for it 10 milliseconds
That's not what your code does. The join should be in the main thread, not in the newly created thread:
Thread2 myThread = new Thread2();
myThread.start();
myThread.join(10);
I assume the whole idea of this exercise is to see the difference between two threads with different priorities. Giving a thread a lower priority may delay its scheduled execution. When the main thread waits for a smaller duration for the new thread to finish, the outputs of the two threads may interleave since the main thread may continue to reach the System.out before the second thread does.
The documentation of the Thread class explains what a thread priority is:
Every thread has a priority. Threads with higher priority are executed in preference to threads with lower priority.
In general, don't extend Thread, you should wrap a Runnable instead.
The Thread priority is
just a hint, the OS can and does ignore it if you don't have the right permissions.
It will only matter if you don't have free CPU. If you have free CPU every thread which wants to run can run.
it really won't matter if you are putting your thread to sleep. e.g. a join.
The only difference it could make is when your machine is very busy, it would take a little longer to wake up from the sleep. e.g. instead of taking say 500 to 501 ms to do the join, it might take 510 ms sometimes.
how can I use join method ?
The purpose of join is to wait for another thread to finish up to some time limit. If you join on yourself, this is effectively the same as Thread.sleep I suggest using Thread.sleep instead as this is less confusing.
First, from the documentation for Thread:
Waits at most millis milliseconds for this thread to die. A timeout of 0 means to wait forever.
So when you have two Thread instances, lets say the current one and a new one, you can cause the current thread to wait for the new one to die:
final Thread t = new Thread(() -> System.out.println("Test"));
t.start();
t.join();
So now our current thread (the one creating t) will wait for t to die, then continue. This method makes an asynchronous task synchronous.
Now, what does calling join in a Thread do? Well, it means that the thread will wait for itself to die. This is the same as TimeUnit.MILLISECONDS.sleep().
So what does your code actually do?
Well, main calls the following code:
Thread2 myThread = new Thread2();
myThread.start();
System.out.println("main thread");
There is nothing here that makes main wait for anything, main dies.
Now your Thread2 (terrible name for a class) does the following:
setPriority(MIN_PRIORITY);
join(500);
System.out.println("Hello Friends from thread2");
So it sets its own priority, it then waits for 500 milliseconds for itself to die. Obviously it doesn't die in that time. It then prints.
TL;DR: setPriority does next to nothing in this code
One further note, do not extends Thread, use a Runnable.
Here the synchronized block is not working:
class NewThreadt extends Thread {
synchronized void dota(){
for(int i = 5; i > 0; i--)
{
System.out.println(i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
System.out.println("Child interrupted.");
}
}
}
// This is the entry point for the second thread.
public void run() {
dota() ;
System.out.println("Exiting child thread.");
System.out.println(Thread.currentThread()); //gives the name of thread
}
}
class trial {
public static void main(String args[]) {
NewThreadt t=new NewThreadt();
NewThreadt q=new NewThreadt();
t.start();
q.start(); both are in main
System.out.println("Main thread exiting.");
}
}
Output:
Main thread exiting.
5
5
4
4
3
3
2
2
1
1
But when I make the following changes the Synchronized Block works:
class NewThreadt implements Runnable //instead of class NewThreadt extends Thread
NewThreadt abc=new NewThreadt(); //Changes in main()
Thread t=new Thread(abc);
Thread q=new Thread(abc);
t.start();
q.start();
Output:
Main thread exiting.
5
4
3
2
1
5
4
3
2
1
Why is this happening? Aren't both of these examples supposed to work the same?
Synchronization depends on sharing a common lock. The synchronized keyword on an instance method means that for a thread to enter that method it first has to acquire the lock on this.
In your first example there is no shared lock, each of the two threads is locking on itself. Each thread acquires its own lock and nobody blocks, the two threads run concurrently. (The only locking going on here is that when a thread wants to write to the console it has to acquire the console's lock first, so that each println takes place atomically.)
In the second example the same Runnable is passed into each thread, so they both lock on the same object, the Runnable. One thread acquires the lock and executes, the other has to wait for the first thread to release the lock.
If you change the second example to give each thread a separate Runnable:
Thread t=new Thread(new NewThreadt());
Thread q=new Thread(new NewThreadt());
t.start();
q.start();
then you'll see synchronization doesn't work and it behaves like the first example.
I have read daemon threads are low priority threads and it runs only when no other user threads are alive. But the below code does not have any difference.
public class DaemonThreadTest {
public static void main(String[] args) {
DaemonThread d = new DaemonThread();
Thread t1 = new Thread(d,"daemon");
t1.setDaemon(true);
Thread t2 = new Thread(d,"Non-Daemon");
t1.start();
t2.start();
System.out.println("Main finished");
}}
class DaemonThread implements Runnable{
public void run(){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
for(int i=0;i<10;i++){
System.out.println(Thread.currentThread().getName()+ i);
}
}}
And the output is,
Main finished
Non-Daemon0
Non-Daemon1
Non-Daemon2
Non-Daemon3
Non-Daemon4
Non-Daemon5
Non-Daemon6
Non-Daemon7
daemon0
daemon1
daemon2
daemon3
daemon4
daemon5
daemon6
daemon7
daemon8
daemon9
Non-Daemon8
Non-Daemon9
Threading priorities are largely handled by the operating system and so it plays a big part in deciding when to allow Threads to run. For example I ran your code a couple of times and on one run I got this output:
Main finished
daemon0
daemon1
daemon2
daemon3
daemon4
daemon5
daemon6
daemon7
daemon8
daemon9
Non-Daemon0
Non-Daemon1
Non-Daemon2
Non-Daemon3
Non-Daemon4
Non-Daemon5
Non-Daemon6
Non-Daemon7
Non-Daemon8
Non-Daemon9
Which is almost a complete reverse to your results. Whilst you can try setting priorities manually it will still ultimately come down to how the operating system runs your threads.
Regarding Daemon threads, a daemon is like a 'sub-thread' (or child thread as I like to think :) ) of a user thread. This means it is linked/connected to a user Thread. In your case it is linked to the main thread, when the main thread ends the daemon will die with it. HOWEVER because you have another user Thread running (t2) the main method waits until that is finished. If you were to comment out t2 like so:
// Thread t2 = new Thread(d,"Non-Daemon");
t1.start();
// t2.start();
and then run your program you would likely find the daemon thread never runs because main ends too soon and when it exits takes the daemon thread with it.
Priority Check
Change your loop code statement to this:
System.out.println(Thread.currentThread().getName()+ i
+ " [Proirity] " + Thread.currentThread().getPriority());
And you can see the priority for yourself. Priority is scaled from 1 -10, when I ran it both t1 and t2 had priority 5 so netiher was lower than the other.
i heard, sleep() will lock the current sync method/block
But here, when i call sleep() on thread 1, thread 2 is able to access the same block? Can anyone Explain?
Main.java
public class Main {
public static void main(String args[])
{
Thread1 t1 = new Thread1();
Thread2 t2 = new Thread2();
System.out.println("going to start t1");
t1.start();
System.out.println("going to start t2");
t2.start();
}
}
=====================================================================
Thread1.java
public class Thread1 extends Thread{
public void run() {
Syncc s1 = new Syncc();
s1.me("T1:");
}
}
=====================================================================
Thread2.java
public class Thread2 extends Thread{
public void run() {
Syncc s2 = new Syncc();
s2.me("T2:");
}
}
=====================================================================
Syncc.java
public class Syncc{
public void me(String s){
synchronized(this){
for(int i=0; i<=5; i++)
{
System.out.println(s+" "+" "+i);
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
==========================================
Output:
going to start t1
going to start t2
T2: 0
T1: 0
T2: 1
T1: 1
T1: 2
T2: 2
T1: 3
T2: 3
T1: 4
T2: 4
T2: 5
T1: 5
BUT according to sleep() method, it should not unlock the current synchronization block right? if so the out put should be..
going to start t1
going to start t2
T1: 0
T1: 1
T1: 2
T1: 3
T1: 4
T1: 5
T2: 0
T2: 1
T2: 2
T2: 3
T2: 4
T2: 5
i mean after thread 1 execution only thread 2 should start right?
Whats the issue?
This is because you have two different instances of Syncc in play here. Each thread has its own copy of Syncc.
Try doing the same with a single instance. You could also synchronize on the static context and try.
To simulate, modify Thread1 and Thread2 to accept an instance of Syncc.
public class Thread1 extends Thread {
private Syncc syncc;
public Thread1(Syncc syncc) {
this.syncc = syncc;
}
public void run() {
this.syncc.me("T1:");
}
}
You can then start them as so:
public static void main(String args[]) {
Syncc syncc = new Syncc();
Thread1 t1 = new Thread1(syncc);
Thread2 t2 = new Thread2(syncc);
System.out.println("going to start t1");
t1.start();
System.out.println("going to start t2");
t2.start();
}
Rules of Sleep, Yield and Join
Sleeping is used to delay execution for a period of time, and no locks are
released when a thread goes to sleep.
A sleeping thread is guaranteed to sleep for at least the time specified in
the argument to the sleep() method (unless it's interrupted), but there is
no guarantee as to when the newly awakened thread will actually return to
running.
The sleep() method is a static method that sleeps the currently executing
thread's state. One thread cannot tell another thread to sleep.
The setPriority() method is used on Thread objects to give threads
a priority of between 1 (low) and 10 (high), although priorities are not
guaranteed, and not all JVMs recognize 10 distinct priority levels—some
levels may be treated as effectively equal.
If not explicitly set, a thread's priority will have the same priority as the
priority of the thread that created it.
The yield() method may cause a running thread to back out if there are
runnable threads of the same priority. There is no guarantee that this will
happen, and there is no guarantee that when the thread backs out there
will be a different thread selected to run. A thread might yield and then
immediately reenter the running state.
The closest thing to a guarantee is that at any given time, when a thread
is running it will usually not have a lower priority than any thread in the
runnable state. If a low-priority thread is running when a high-priority thread
enters runnable, the JVM will usually preempt the running low-priority
thread and put the high-priority thread in.
When one thread calls the join() method of another thread, the currently
running thread will wait until the thread it joins with has completed. Think
of the join() method as saying, "Hey thread, I want to join on to the end
of you. Let me know when you're done, so I can enter the runnable state."
http://www.amazon.com/SCJP-Certified-Programmer-Java-310-065/dp/0071591060
You have created two Synch objects each object corresponding to one thread . Each object has its own copy of me. Hence when your start each thread, withing the run method the thread is calling its own copy of the function me. Since the two thread act only on their copy this works like a single thread scenario. If you do want to test a multithread scenario then make the method me static(class level method) and apply a class level lock.
Thread1.java
public class Thread1 extends Thread{
public void run() {
Syncc.me("T1:");
}
}
Thread2.java
public class Thread2 extends Thread{
public void run() {
Syncc.me("T2:");
}
}
Syncc.java
public class Syncc{
public static void me(String s){
synchronized(Syncc.class){
for(int i=0; i<=5; i++)
{
System.out.println(s+" "+" "+i);
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}