В этом коде есть ошибка:
synchronized (client.getStatus()) {
client.setStatus(ClientState.successfulRegistration);
client.getStatus().notifyAll()
}
Вам разрешено только notifyAll () для заблокированного вами объекта.Но одна строка над вами заменила объект другим.Это действительно плохая идея, чтобы изменить объект блокировки.Обычно вы будете использовать «это» или вы используете частный объект.
Я бы предложил следующее решение:
public synchronized void setStatus(T status) {}
public synchronized T getStatus() {}
Методы wait () и notifyAll () нужны только в том случае, если вы ожидаете условие и хотите снять блокировку.Вот пример:
public synchronized void add(T element) {
while(full) {
wait();
}
data.add(element);
notifyAll();
}
public synchronized T remove() {
while(empty) {
wait();
}
T item = data.getAndremove();
notifyAll();
return item;
}
В этом примере много скрытых понятий.Во-первых, вам нужно время ожидания для ожидания.Потому что, если вы подождете и получите уведомление, вы вернетесь в очередь для запуска.Но вы не знаете, выполняется ли условие так, что вам придется перепроверять условие.Вот почему вы используете цикл while вместо if ().
Вторая концепция известна по уведомлению и возобновлению.Можно уведомить () и сохранить блокировку.Таким образом, вам не нужно ставить notify () в конце.
Третья концепция - это различие между notify () и notifyAll ().Первый пробуждает только одну нить.Если данные пусты, и вы просыпаетесь в потоке, который хочет что-то удалить, чтобы была тупиковая блокировка.Если вы разбудите всех, все проверит, выполнено ли условие, и попытайтесь продолжить.
Вот еще один пример, который больше соответствует вашему коду:
public synchronized void doSth() {
while(client.getStatus.equals("WAIT") {
wait();
}
System.out.println("Status isn't wait");
}