I have tried this code. But after printing 0 , it doesn't print anything. It is blocking due to some lock I think.
public class EvenOdd implements Runnable {
private Object o = new Object();
private volatile int i = 0;
public void run() {
try {
System.out.println();
if ( Thread.currentThread().getName().equals( "Even")) {
printEven();
} else {
printOdd();
}
} catch ( Exception ee) {
ee.printStackTrace();
}
}
private void printEven() throws InterruptedException {
while ( true) {
synchronized ( o) {
while ( this.i % 2 == 0) {
o.wait();
}
System.out.println( Thread.currentThread().getName() + i);
i++;
o.notify();
}
}
}
private void printOdd() throws InterruptedException {
while ( true) {
synchronized ( o) {
while ( this.i % 2 != 0) {
o.wait();
}
System.out.println( Thread.currentThread().getName() + i);
i++;
o.notify();
}
}
}
}
My TestClass:
EvenOdd x = new EvenOdd();
new Thread(x,"Even").start();
new Thread(x,"Odd").start();
Where am I wrong? Thank.
PS : I know this type of question has been asked many times , but I want to try by my own.
My guesses is you are;
EDIT: After running the code the OP fixed the code, it prints
0
1
as expected. It may sometimes print 0 and 0 randomly as the first check for odd/even is not synchronized.
It's a simple deadlock:
Thread 1 waits for someone to notify on the lock. Thread 2 waits for someone to notify on the same lock.
Since no one ever gets to o.notify();
, nothing happens.
And i
is 0 when both threads start, so both first call printEven()
. Now when that has happened, both threads will then call printOdd()
in the next round.
The basic concept is when one thread is running, the other has to wait. Once the thread prints the value, it has to wait until the other thread prints. This is achieved by using wait/notify mechanism.
When Odd thread completes printing the value, it notifies the waiting thread(Even thread) and the Even thread becomes ready to run but will wait for the lock to be released by the Odd thread. Now the odd thread calls wait on the locker object so that it releases the lock and goes to wait state. At this point, the only thread waiting for locker object's lock is Even thread and it runs. This process continues alternatively.
public class Test {
public static void main(String[] args) {
Object locker = new Object();
Thread t1 = new Thread(new OddWorker(locker));
Thread t2 = new Thread(new EvenWorker(locker));
t1.start();
t2.start();
}
}
class OddWorker implements Runnable {
private Object locker;
private int number = 1, count = 1;
OddWorker(Object locker) {
this.locker = locker;
}
@Override
public void run() {
synchronized (locker){
do {
try {
System.out.println(Thread.currentThread().getName() + ": " + number);
number += 2;
locker.notify();
locker.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} while(++count < 11);
locker.notify();
}
}
}
class EvenWorker implements Runnable {
private Object locker;
private int number = 2, count = 1;
EvenWorker(Object locker) {
this.locker = locker;
}
@Override
public void run() {
synchronized (locker){
do {
try {
System.out.println(Thread.currentThread().getName() + ": " + number);
number += 2;
locker.notify();
locker.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} while(++count < 11);
}
}
}
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.