Reputation: 31
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
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