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.
Related
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.
I'm trying to run four threads. run() method has a for loop that loops 10 times.In each loop the shared resource "x" is increment by 1. When all threads die, the for loop should have run 4x10 =40 times and x value should equal 40.
That is not happening in all runs of the my code.Each time I run the code it prints a different value of x.Most of the output values of x range from 33 to 40.
Why is it not 40 in every run? Does that mean some for loop loops are being skipped? Is it caused due being blocked?
NOTE : this does not happen when sleep() is removed. It prints 40 every single time.
My code :
public class MyThreadImplementsRunnable implements Runnable{
int x =0;
public void run() {
for(int i=0;i<10;i++){
x = x+1;
try {
Thread.sleep(1);
} catch (InterruptedException e) {
System.out.println("exception");
e.printStackTrace();
}
}
}
public static void main(String[] args) {
MyThreadImplementsRunnable m = new MyThreadImplementsRunnable();
Thread t1 = new Thread(m,"first");
Thread t2= new Thread(m,"second");
Thread t3= new Thread(m,"third");
Thread t4= new Thread(m,"fourth");
t1.start();
t2.start();
t3.start();
t4.start();
//To make sure not to go the next statement unless all threads die
while(t1.isAlive()|| t2.isAlive()|| t3.isAlive()||t4.isAlive()){
}
//After all threads die
System.out.println("now all threads are dead");
//value of the shared resource x after all threads exit
System.out.println(m.x);
}
}
Some test runs gave the following results :
Output:
now all threads are dead
34
Output:
now all threads are dead
33
x = x + 1 loads the value of x from memory, adds 1 to it and then stores it in x. Lets say Thread t1 loads 30 and at the same time thread t2 loads 30 they both increment 30 by 1 and store 31 in x instead of 32.
Why it's always 40 without sleep can be caused by many things I hypothesize that it's caused by each of the threads running very quickly and finishing before the next one starts.
You also don't use volatile and there are visibility issues but for now lets not get into that. This is also something you need to learn if you want to write multi-threaded code.
You are using a shared resource(x) between threads which is bound to create many problems like data race, visibility.. Your answer will be always different
#oleg I don't think Volatile will help in this scenario
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.
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.
/* Multiple Threads Executing
* Author Myth17
*/
class T1 implements Runnable
{
public void run()
{
for(int c=0;c<10;c++)
System.out.println(Thread.currentThread().getName()+" running....");
}
}
class T2 implements Runnable
{
public void run()
{
for(int c=0;c<10;c++)
System.out.println(Thread.currentThread().getName()+" running....");
}
}
class T3 implements Runnable
{
public void run()
{
for(int c=0;c<10;c++)
System.out.println(Thread.currentThread().getName()+" running....");
}
}
class Rt
{
public static void main(String args[])
{
T1 j1=new T1();
T2 j2=new T2();
T3 j3=new T3();
Thread w1=new Thread(j1);
w1.setName("S");
Thread w2=new Thread(j2);
w2.setName("N");
Thread w3=new Thread(j3);
w3.setName("M");
w1.start();
w2.start();
w3.start();
}
}
If the loop runs up to 3 in the three for loops, in Linux Java JVM each thread executes serially as SSSNNNMMM (9 lines).
I changed the loop to run up to 10 in each for loops. I was expecting 30 lines and a change in order. But strangely S never executes and program exits!!
Shouldn't S get its chance sooner or later? As what I have read is that apart from deamon threads JVM shuts only after user thread complete.
alt text http://img36.imageshack.us/img36/6646/69458021.png
Did you realize that there are 8 lines of N in your output folder and 10 lines of M. It seems that the output window just displays 18 lines. S runs but you cannot see it.
Can you try incrementing loop to 20 instead of 10. I guess you will just see 18 lines of M.
(It seems that the problem is just not having a scroll bar on output window. Resize should work if exists.)
In your snippet neither of the threads are daemon. And until you set the threads as daemon via Thread#setDaemon() all the threads will execute completely before the app exits.
Recheck your problem!!
This should have worked. You could put log in the run() methods or debug it using break points.
You only have 18 lines showing in the window.
All of the "S" lines have scrolled off, as well as two of the "N" lines.
I tried running your code on a Windows Sun JVM 1.6 and as expected, I got 30 lines. What kind of JVM are you using?
All non daemon threads should finish before the JVM exists.