Я все еще новичок в потоках, и я работал над простой программой, которая должна использовать два потока, которые оба увеличивают общий "счетчик" (интерфейс, реализованный классом "SychronizedCounter"). Они оба должны делать это установленное количество раз и всегда в повторяющейся последовательности (например, 01010101 .... (числа, обозначающие идентификатор потока (пользовательский заданный идентификатор, хранящийся в переменной)).
Я просто вставлю здесь важный код:
public class SynchronizedCounter implements Counter {
int count = 0;
public void increment() {
synchronized (this) {
count++;
}
}
public int value() {
synchronized (this) {
return count;
}
}
}
А вот метод запуска потоков, работающих с экземпляром этого счетчика (будет два из этих потоков):
public void run() {
synchronized (counter) {
for (int i = 0; i < numIterations; i++) {
counter.increment();
counter.notifyAll();
if (id == 0) {
while (counter.value() % 2 != 0) {
try {
counter.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
else {
while (counter.value() % 2 != 1) {
try {
counter.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
//IF I PLACE THE TWO CODE LINES HERE, THE PROGRAM WORKS!
}
}
}
Теперь у меня есть несколько вопросов, касающихся этого примера кода и партиций кода в целом:
Две строки кода counter.increment (); counter.notifyAll (); вызывают мои программа работает бесконечно, если они размещены так, как они указаны выше. При отладке я даже видел потоки, пытающиеся вызвать wait и запускающие в InterruptedException, если две строки кода размещены, как указано выше. Однако, если я помещу их в конце (где комментарий), программа выполняется просто отлично. Почему? В чем здесь разница?
Я заметил, что вызовы "уведомлять" всегда выполняются на е ин кода блока. Это почему? Опять же, если я сделаю это в моем примере кода, моя программа будет работать нормально. Есть ли соединение?
Если бы я поместил синхронизированный блок в метод run () после заголовка для l oop, чтобы весь синхронизированный блок находился в пределах для l oop, а не для синхронизированного блока для l oop, это что-нибудь изменило бы?
Я очень благодарен за любую помощь!