Rahul V.
Rahul V.

Reputation: 31

Why the two outputs differs?

public class EvenOddWithTwoThreads **extends Thread**
{
private volatile int count = 1;
private volatile boolean flag = false;
@Override
public void run() {
    while(count <=10){
        synchronized (this) {
            while(flag){
                flag= false;
                try {
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println(Thread.currentThread().getName() +count);
            count= count+1;
            flag = true;

            notify();
        }
    }
}

public static void main(String[] args) {

    EvenOddWithTwoThreads ins = new EvenOddWithTwoThreads();
    **Thread t1 = new Thread(ins, "Odd Thread");**
    **Thread t2 = new Thread(ins,"Even Thread");**

    t1.start();
    t2.start();

    }
}

output:

Odd Thread1

Odd Thread2

Odd Thread3

Even Thread4

Odd Thread5

Even Thread6

Odd Thread7

Even Thread8

Odd Thread9

Even Thread10

public class EvenOddWithTwoThreads **implements Runnable**{

private volatile int count = 1;
private volatile boolean flag = false;


@Override
public void run() {
    while(count <=10){
        synchronized (this) {
            while(flag){
                flag= false;
                try {
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println(Thread.currentThread().getName() +count);
            count= count+1;
            flag = true;

            notify();
        }
    }
}

public static void main(String[] args) {

    EvenOddWithTwoThreads ins = new EvenOddWithTwoThreads();
    Thread t1 = new Thread(ins, "Odd Thread");
    Thread t2 = new Thread(ins,"Even Thread");

    t1.start();
    t2.start();

    }
}

output :

Odd Thread1

Even Thread2

Odd Thread3

Even Thread4

Odd Thread5

Even Thread6

Odd Thread7

Even Thread8

Odd Thread9

Even Thread10

Upvotes: 3

Views: 125

Answers (1)

SimoV8
SimoV8

Reputation: 1402

Extending Thread or implementing Runnable doesn't change the behaviour of your code, but in general it's better to use Runnable for the reasons explained here. The two piece of software you showed are equally bugged, it's just a coincidence that the second one is returning the right answer (I tried to run both on my machine and they are returning the right answer).

So, what's happening? At the beginning both threads are in the RUNNABLE state, so both can acquire the intrinsic lock (with the synchronization primitive). In your case it happens that Odd Thread acquire it first, so Even Threads goes in BLOCKED state. Odd Thread print his number and notify (no one in this case). At the end of the loop it releases the intrinsic lock and start the loop again. Now Even Thread is no more blocked by the lock, so both threads can try to acquire again the intrinsic lock: this is called Race Condition, meaning that the output is dependent on the timing with which the two threads are executed.

In the first case Even Thread is faster and acquire the lock, but since flag is now true it goes in WAITING state, releasing the lock that is used by Odd Thread to print "Odd Thread2" and notify Even Thread that goes in BLOCKED state (for further details see here). At the end of the loop Odd Thread release the lock and we are again in the same situation in which both threads can acquire the lock: in the worst case scenario Even Thread could always goes first and stay trapped in the while loop, waiting while Odd Thread does all the job.

Upvotes: 3

Related Questions