Это вопрос интервью, и я не думаю, что он имеет какое-либо отношение к практическим проблемам реальной жизни. Мне нужно печатать числа 12345.... последовательно, но условие состоит в том, что я должен печатать его, используя два потока, один из которых отвечает за печать нечетных чисел, а другой - за четные числа.
до сих пор я придумал это решение.
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
при написании этого кода я заметил одно странное поведение, которое не понял. Если в LINE-1,2,3,4 в приведенном выше коде я пишу number
вместо this.number
, моя числовая переменная экземпляра не увеличивается, и код просто печатает бесконечное количество единиц.
Я предполагаю, что оба метода printEven
и printOdd
вызываются для самого исполняемого экземпляра, тогда почему его значение не увеличивается. Я попытался сделать number
изменчивым, но все равно это привело к тому же результату.
2
Также я вижу, что числа печатаются до 11, а не до 10. Я понимаю, почему это происходит (последний вызов printOdd получает уведомление о последнем вызове printEven (который печатает 10), поэтому печатает 11), один из способов избежать этого - проверять номер каждый раз перед печатью и смотреть, находится ли он в пределах лимита, но я хотел знать, что было бы лучше способ преодолеть это.
Спасибо.
Параметр метода EDIT number
полностью лишний и может быть опущен. Это условие if(this.max>=number) можно использовать перед печатью числа.