I was working on Threads and decided to add some extra text before and after my focused lines of code are run, for reference. I expected to get one 'extra-text' towards the start and the other at the end. However... that's not happening and the second 'extra-text' just comes at the fourth position when I run it. I am a beginner and need to know why this is happening...
---CODE---
class Hi extends Thread{
public void run(){
for(int i=1; i<=5; i++){
System.out.println("HI!");
try{
Thread.sleep(500);
} catch(InterruptedException e){}
}
}
}
class Hey extends Thread{
public void run(){
for(int i=1; i<=5; i++){
System.out.println("HEY!");
try{
Thread.sleep(500);
} catch(InterruptedException e){}
}
}
}
public class MyClass {
public static void main(String[] args){
Hi hiObj = new Hi();
Hey heyObj = new Hey();
System.out.println("extra-text");
hiObj.start();
heyObj.start();
try {
Thread.currentThread().sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("extra-text");
}
}
---OUTPUT---
extra-text
HI!
HEY!
extra-text
HEY!
HI!
HEY!
HI!
HEY!
HI!
HEY!
HI!
This is a common concurrency error.
The main method of your program runs on the main thread. Thus, before you've started the hiObj
and heyObj
threads, you already have one thread. After you start both of the new threads, you have three. Each executes concurrently. This means that each thread can execute code without waiting for the others. Order is not guaranteed between threads.
This causes the behavior you observe. Before hiObj
or heyObj
are started, the main method running on the main thread prints "extra-text"
. Next, hiObj and heyObj are started. The main thread reaches the line Thread.currentThead().sleep(10)
which causes it to suspend execution for 10 milliseconds. On most machines (including yours), this is enough time for the other two threads to begin execution. Each thread begins the for
loop in its run
method and prints either "HI"
or "HEY"
. Thus, the first three lines of output are (the order of "HI"
and "HEY"
are not guaranteed):
"extra-text"
"HI"
"HEY"
Next, the hiObj
and heyObj
threads reach the line Thread.sleep(500)
which causes them to suspend execution for 500 milliseconds. After 10 milliseconds have passed, the main thread will be finished sleeping a will resume. Note that neither the hiObj
or heyObj
threads could have resumed by now. Thus, the next line printed will be the from the next line executed in main
. This is "extra-text"
. Thus, the expected output is:
"extra-text"
"HI"
"HEY"
"extra-text"
Over the next few seconds, the remaining prints from the hiObj
and heyObj
threads will occur. In Java, the main thread exits only after all other threads have exited (unless System.exit
is called or there is an uncaught exception). In this case this means the program will only exit when main
reaches the end of execution and when both hiObj
's and heyObj
's run methods return.
To change your program so that the last "extra-text"
always prints at the end, you have to cause the main thread to wait for the hiObj
and heyObj
threads to finish. In Java, there is a method on Thead
called join
which causes the calling thread to wait until the joined thread dies. In your program, you can modify MyClass
to look like this:
public class MyClass {
public static void main(String[] args){
Hi hiObj = new Hi();
Hey heyObj = new Hey();
System.out.println("extra-text");
hiObj.start();
heyObj.start();
try {
Thread.currentThread().sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
hiObj.join();
heyObj.join();
System.out.println("extra-text");
}
}
With this change, main
will first wait for hiObj
to finish and then wait for heyObj
to finish before it prints "extra-text"
.
If you get rid of the
Thread.currentThread().sleep(10);
in the main Method you will see that your two extra texts are printed to the console immediately after execution. By using the sleep(10) you just delay the second extra text and in the meantime your 2 threads print their first output.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.