I am trying to print all numbers in the Array, starting from 1 at index 0 and ending at 11 at last. There are two threads which are doing this one is printing only the even number and second is printing only the odd numbers.
Here is the code.
class PrintEvenOdd {
static class SourceData {
int[] arr;
volatile int counter;
public SourceData(int[] commonArr, int counter){
this.arr = commonArr;
this.counter = counter;
}
public void getData(){
try{
synchronized(this){
while((counter%2==0 && Thread.currentThread().getName().equalsIgnoreCase("odd")) || (counter%2!=0 && Thread.currentThread().getName().equalsIgnoreCase("even"))){
wait();
}
System.out.println(counter+ " : " + Thread.currentThread().getName());
notify();
}
}catch(Exception ie){
ie.printStackTrace();
}
}
}
static class Even extends Thread{
SourceData sd;
public Even(SourceData sd){
this.sd = sd;
}
@Override
public void run(){
while(sd.counter < 12) {
sd.getData();
sd.counter++;
}
}
}
static class Odd extends Thread{
SourceData sd;
public Odd(SourceData sd){
this.sd = sd;
}
@Override
public void run(){
while(sd.counter < 12) {
sd.getData();
sd.counter++;
}
}
}
public static void main(String[] args){
int[] commonArr = new int[11];
for(int i = 0; i < commonArr.length; i++){
commonArr[i] = i;
}
int counter = 0;
SourceData sd = new SourceData(commonArr, counter);
Even even = new Even(sd);
even.setName("EVEN");
even.start();
Odd odd = new Odd(sd);
odd.setName("ODD");
odd.start();
}
}
The problem with this code is that its printing only the two values, shown here,
0 : EVEN
1 : ODD
What changes should I do so that the code prints all the values till the end of the array?
Here's what's happening: EVEN runs, increments the counter to 1, and then in the next getData
it starts waiting. Then ODD runs, increments the counter to 2, and then it too starts waiting in getData
. You have two threads waiting with no chances of waking up.
To fix it, you have to notify when the condition a thread is waiting on changes. That is: notify after sd.counter++
, so the other thread can wake up. Since the other thread is waiting on sd
, you have to call:
sd.counter++
sd.notify()
Also note that ODD and EVEN threads are identical. You can have one class implementing the thread, and create two instances of it.