For the given code snippet:
public static void main(String[] args) throws InterruptedException {
Runnable r = new Runnable() {
public void run() {
System.out.print(Thread.currentThread().getName());
}
};
Thread t1 = new Thread(r, "One ");
t1.start();
t1.sleep(2000);
Thread t2 = new Thread(r, "Two ");
t2.start();
t2.sleep(1000);
System.out.print("Main ");
}
The output is always coming as "One" "Two" "Main". Why is such behavior with threads in this code? Why always "t1" is starting first and not "t2" or main thread for that matter?
Thread.sleep() is a static method which pauses the current thread. The "current" thread here means the "thread from which the sleep() call was invoked": in this code that is always the main thread.
So your code is equivalent to, and should be written as
public static void main(String[] args) throws InterruptedException {
Runnable r = new Runnable() {
public void run() {
System.out.print(Thread.currentThread().getName());
}
};
Thread t1 = new Thread(r, "One ");
t1.start();
Thread.sleep(2000);
Thread t2 = new Thread(r, "Two ");
t2.start();
Thread.sleep(1000);
System.out.print("Main ");
}
What happens is that you start t1, pause the main thread for two seconds, then start t2, pause the main thread for another second, and then print "Main " to the console.
Technically, there is no guarantee as to how long it will be between calling t1.start() and System.out.println("One ") (from t1's runnable), and there is no guarantee as to how long it will be between calling t2.start() and System.out.println("Two "). For all practical purposes, though, these will be at most of the order of milliseconds.
However, you are guaranteed that there will be at least two seconds between calling t1.start() and t2.start(), and that there will be at least one second between calling t2.start() and System.out.println("Main ").
So for all practical purposes, you will print "One " to the console, then two seconds (plus or minus a few milliseconds, at most) later print "Two " to the console, then another second (plus or minus a few milliseconds) later print "Main ".
Any good (and reasonably configured) IDE will warn you when you refer to a static method via an object reference, as you do with t1.sleep(2000), etc. You should not ignore these warnings and should correct the code, so that it is clearer what you are doing.
here we have total three threads main, t1, t2. when execution starts all the threads in pool are executing in asynchronously, because threads of the same priority are given equal treatment by the java scheduler and, therefore they run on a first-come, first-serve basis.
use threadname.setPriority(intNum) method to assign priority, which affects the order of running threads.
Related
I am wondering what happens in the following scenario:
Two threads are created:
Thread t1 = new Thread();
Thread t2 = new Thread();
Assume these just print out a string, the threads then call the .start() method:
t1.start();
t2.start():
My question is why do these threads print in a seemingly random order each time? I know threads execute concurrently but would t1 not always finish before t2 due to the sequential execution of the main process?
Calling start() on a Thread doesn't necessarily result in the thread running immediately after. It is possible for other things to happen in between your calling start() and the first line of your thread's run() method actually being run. And even once your run() is actually running, it's also possible that other things happen before, during, or after your run() method finishes.
In your question, you said: "assume these just print out a string" – here's an implementation of run() which does that:
public void run() {
System.out.println("my name is: " + getName());
}
So it's possible that t1 starts to run first, but before it actually calls System.out.println, t2 is allowed to execute and runs to completion, then t1 is resumed.
If this kind of behavior won't work for your use case, you'll need to add some kind of concurrency protection to coordinate how and when your threads run.
UPDATE:
To illustrate the unpredictable sequence of thread execution, run this code a few times and observe the output:
public class Example {
public static void main(String[] args) {
for (int k = 0; k < 10; k++) {
new TestThread(k).start();
}
}
}
class TestThread extends Thread {
private final int k;
TestThread(int k) {
this.k = k;
}
#Override
public void run() {
System.out.print(k + " ");
}
}
Here is the output from one of my local runs:
7 0 1 5 4 6 3 2 8 9
Thread.start() doesn't guarantee execution. It will just make the Thread state runnable and hand over to the Thread Scheduler. It is the Thread Scheduler which decides which thread to run when.
If you need code to execute in a defined order on multiple threads, you need to add synchronization code between those threads.
Otherwise, the system is free to schedule execution in any order it sees fit.
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.
I am unable to understand that if my variable is both volatile and static then why threads are not reflecting the common shared value in the output
Output of last few lines is :
Thread is running
4998Thread-0
Thread is running
4999Thread-0
Thread is running
4899Thread-1
Thread is running
public class Test implements Runnable{
volatile static int i=0;
#Override
public void run() {
for(;i<5000;i++)
{ try {
Thread t = Thread.currentThread();
String name = t.getName();
// Thread.sleep(10);
System.out.println(i+name);
} catch (Exception ex) {
ex.printStackTrace();
}
System.out.println("Thread is running");
}}
public static void main(String[] args) {
Test t=new Test();
Thread t1=new Thread(t);
Thread t2=new Thread(t);
t1.start();
// t.run();
t2.start();
}
}
You can't use a compound (multi step) operation like i++ on a volatile variable.
You can have both threads retrieve the value, increase it, and write it back resulting in one lost increment (as you see in your example).
Volatile ensures that changes to the variable are visible to other threads. But it does not ensure synchronization.
From one execution of your program I get this output :
Thread is running
3474Thread-1
Thread is running
3475Thread-0
Thread is running
3477Thread-0
(.... many lines where i goes from 3478 to 4998, with Thread-0 always being the one running...)
Thread is running
4999Thread-0
Thread is running
3476Thread-1
Thread is running
This happens because threads get slices of processor time to be run and their execution can be paused and resumed at any point.
Here Thread-1 is executing line "System.out.println(i+name);" with i having a value of 3476. i+name is evaluated to "3476Thread-1" but just then the Thread-1 execution stops and instead Thread-0 gets its time slice. Thread-0 executes till finalization. And then Thread-1 gets again to execute. We have left it after i+name had been evaluated to "3476Thread-1" and before the call to println. The call is now completed and printed, hence you see "3476Thread-1" at then end. i has been increased to 5000 by Thread-0 but that does not change the result of the evaluation of i+name which was done before all those increases.
The problem is that i++ and i+name are different instructions and thread execution can be paused and resumed between them. To ensure that you get a secuential output you need to ensure than there is no interruption between i++ and i+name. That is, you need to make that set of instructions atomic.
public class Test implements Runnable{
static Object lock = new Object();
volatile static int i=0;
#Override
public void run() {
for(;;)
{
try {
Thread t = Thread.currentThread();
String name = t.getName();
synchronized( lock )
{
if ( i>=5000 )
break;
i++;
System.out.println(i+name);
}
// Thread.sleep(10);
} catch (Exception ex) {
ex.printStackTrace();
System.out.println("Thread is running");
}
} }
public static void main(String[] args) {
Test t=new Test();
Thread t1=new Thread(t);
Thread t2=new Thread(t);
t1.start();
// t.run();
t2.start();
}
}
In that program, if Thread-1 gets paused between i++ and i+name it will be inside the a critical section controlled by synchronized(lock). When Thread-0 gets to execute it will reach the synchronized(lock) instruction and will have to stop executing until Thread-1 resumes and gets out of that block. Because the JLS ensures that :
The synchronized statement (§14.19) computes a reference to an object;
it then attempts to perform a lock action on that object's monitor and
does not proceed further until the lock action has successfully
completed. After the lock action has been performed, the body of the
synchronized statement is executed. If execution of the body is ever
completed, either normally or abruptly, an unlock action is
automatically performed on that same monitor.
Here's a code snippet I learned usage of volatile keyword from:
import java.util.concurrent.TimeUnit;
public class VolatileDemo {
private volatile static boolean stop; //remove volatile keyword to see the difference
private static int i = 0;
public static void main(String[] args) throws InterruptedException {
Thread otherThread = new Thread(new Runnable() {
public void run() {
while (!stop)
i++;
}
});
otherThread.start();
TimeUnit.SECONDS.sleep(1);
stop = true;// main thread stops here and should stop otherThread as well
}
}
If you want to observe what volatile does, try to remove it and then follow the execution, this should be obvious after you run those two versions, but basically keyword here prevents java compiler from assuming that stop condition never changes, it will be read every time the condition gets evaluated. Neat, isn't it?
By looking at your code the problem isn't with usage of volatile keyword, the problem is that the expression i++ is not atomic. It actually is 3 step operation:
1) fetch value of i;
2) increment i;
3) save new value of i
When multi-threading comes into play, these might or might not be mixed with other thread's instructions.
So the execution might look like that as well:
1) T1: fetch i;
2) T2: fetch i;
3) T1: increment i;
4) T2: increment i;
5) T1: save i;
6) T2: save i;
If i was 0 you thought you will get 2 as the output, and here's 1 instead.
Go with synchronization, which is pretty simple when not overused and well thought.
Suggested read on synchronization
If two threads are both reading and writing to a shared variable, then using the volatile keyword for that is not enough. You need to use synchronization in that case to guarantee that the reading and writing of the variable is atomic.
Therefore you need to use synchronization when you modify the i value.
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.
my task is to create thread in this order: if A start->start B and C, if B start->start D.
And destroy them in reverse order If D then B. If B and C then A. I hope you get it. I manage to do it but I guess there is better way to do it. Do you have any suggestions?
After your comments i have changed my code and it is much more simply. But now it looks "stupid". I would like to change hardcore of if statements and implementation, any advice? tnx for advice I'm learning with you.
This is my new code:
import java.util.*;
class RobotController implements Runnable{
String name;
public void run() {
Thread t = Thread.currentThread();
System.out.println(t.getName() + " status = " + t.isAlive());
System.out.println(t.getName() + " status = " + t.getState());
}
public static void main(String args[]) throws InterruptedException{
Thread thread_A = new Thread(new RobotController(), "Thread A");
Thread thread_B = new Thread(new RobotController(), "Thread B");
Thread thread_C = new Thread(new RobotController(), "Thread C");
Thread thread_D = new Thread(new RobotController(), "Thread D");
thread_A.start();
thread_A.join();
System.out.println(thread_A.getState());
thread_B.start();
thread_B.join();
System.out.println(thread_B.getState());
thread_C.start();
thread_C.join();
System.out.println(thread_C.getState());
thread_D.start();
System.out.println(thread_D.getState());
}
}
There are some flaws in your code which will make it not to work accordingly sometimes:
You called thread_A.start() and then checked thread_A.isAlive(). Now what if , thread_A is already completed before thread_A.isAlive() condition is checked?.thread_B and thread_C is never started. Your application fails.
Assume that thread_A is not completed and thread_A.isAlive() condition is passed, then starting of thread_B before thread_C is not always guaranteed by Java thread scheduler. Again your application fails.
Assume that thread_B starts before thread_C and if thread_B completes before thread_B.isAlive() is checked then the if condition fails and thread_D is never started. Again your application fails.
Now a point to ponder:
There is no need to check if the thread is alive after its join() method is called. It is an unnecessary runtime overhead.
EDIT
OK, Here is the modified version of code..I hope it would let you understand the dynamics of thread:
class RobotController implements Runnable
{
private final Object lock = new Object();
private void notifyThread()
{
synchronized(lock)
{
lock.notify();
}
}
public void run()
{
synchronized(lock)
{
try
{
System.out.println(Thread.currentThread().getName() + " started");
lock.wait();
System.out.println(Thread.currentThread().getName()+ " stopped");
}
catch (InterruptedException ex)
{
ex.printStackTrace();
}
}
}
public static void main(String args[]) throws InterruptedException
{
RobotController rca = new RobotController();
RobotController rcb = new RobotController();
RobotController rcc = new RobotController();
RobotController rcd = new RobotController();
Thread thread_A = new Thread(rca,"Thread A");
Thread thread_B = new Thread(rcb,"Thread B");
Thread thread_C = new Thread(rcc,"Thread C");
Thread thread_D = new Thread(rcd,"Thread D");
thread_A.start();
while (thread_A.getState() != Thread.State.WAITING)
{
Thread.sleep(100);
}
thread_B.start();
thread_C.start();
while (thread_B.getState() != Thread.State.WAITING && thread_C.getState() != Thread.State.WAITING)
{
Thread.sleep(100);
}
thread_D.start();
while (thread_D.getState() != Thread.State.WAITING)
{
Thread.sleep(100);
}
rcd.notifyThread();
thread_D.join();
rcc.notifyThread();
thread_C.join();
rcb.notifyThread();
thread_B.join();
rca.notifyThread();
}
}
And here is the output:
Thread A started
Thread B started
Thread C started
Thread D started
Thread D stopped
Thread C stopped
Thread B stopped
Thread A stopped
In multi threading, there is no need of synchronization unless the common data is shared by multiple threads.
In your case, you want to start and stop the threads in a particular order. For this, there is join method in Thread class. This link shows good example of join method.
In my opinion, it is quite strange to use synchronized (lock) in your run method to lock your object. The reason is that in each Thread object has the different lock attribute, which is belong to each object. It means you are trying to lock the different objects. Actually, it doesn't make sense.
Basically, the object that you should apply the synchronized are any shared objects. For example, you need to count something and then you create a class object to share it in your class. In this case, it should be locked while being read or written.
I would like to highlight two points here:
Have a look at thread execution life cycle here. It says that, when start() method is called, thread enters in runnable state and not in running state. When thread enters in running state, that means run() method is getting exexuted. CPU/OS decides the priority of which thread should be transferred from runnable to running thread. E.g. if you call start() method for 4 threads, it is not necessary that they will execute in that particular order. (Running the same program in my pc multiple times gives me different outputs.
In your case, when the condition if(thread_A.isAlive()) is executed, it is possible that the thread A may not be in running state. Hence, the control will not go into if which is not correct.
To correct this behavior, in main, a while loop should implemented which waits until the thread becomes alive and so on.
2 . In your program, you have not assigned names to the threads and you are printing the name in the run() method. In this case, JVM assigns the names to threads in order of their execution e.g. first thread to execute will have name as 'Thread-0' and so on. Hence, we will not be able to identify which thread executed first. Assign the names using setName() method.