This an interview question and i don't think it has any relation with practical real life problems.
I have to print numbers 12345.... sequentially but the condition is i have to print it using two threads one responsible for printing odd numbers and one for even numbers.
till now i have come up with this solution.
package junk.concurrency;
public class PrintEvenOddTester {
public static void main(String... args) {
TaskEvenOdd t = new TaskEvenOdd(10);
Thread t1 = new Thread(t, "odd printer");
Thread t2 = new Thread(t, "even printer");
t1.start();
t2.start();
}
}
class TaskEvenOdd implements Runnable {
private int max;
private boolean isOdd = true;
private int number = 1;
TaskEvenOdd(int max) {
this.max = max;
}
synchronized void printEven(int number) { // sync on runnable itself
while (isOdd) { // if odd is to be printed, wait
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Even:" + this.number); // LINE-1
isOdd = true;
this.number++; // LINE-2
notifyAll();
}
synchronized void printOdd(int number) { // sync on runnable itself
while (!isOdd) { // if even is to be printed, wait
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Odd:" + this.number); // LINE-3
this.number++; // LINE-4
isOdd = false;
notifyAll();
}
@Override
public void run() {
while (number <= max) {
if (Thread.currentThread().getName().equals("even printer")) {
printEven(number);
} else {
printOdd(number);
}
}
}
}
1
while writing this code i observed one strange behaviour which i did not understand. If at LINE-1,2,3,4 in above code, i write number
instead of this.number
my number instance variable is not getting incremented and code just prints infinite number of 1s.
I assume both the printEven
and printOdd
method is called on runnable instance itself then why its value is not getting incremented. I tried making number
volatile but still it resulted in same output.
2
Also i see numbers are getting printed till 11 not till 10. I understand why this is happening(as the last call to printOdd gets notified by last call of printEven(which is printing 10) thus prints 11 ), one way to avoid this is to check number every time before printing and see if it's under limit but i wanted to know what would be the best way to overcome this.
Thanks.
EDIT method parameter number
is completely redundant and can be omitted. This if(this.max>=number) condition can be used before printing the number.