Сообщение Re: Синхронизация через enum-переменную от 26.04.2020 2:52
Изменено 26.04.2020 2:53 мамут ушёл, и я пойду
Re: Синхронизация через enum-переменную
F2>И вопрос: а можно ли так делать?
Нельзя
F2>Насколько я понимаю, в джаве элементы enum'а — это объекты этого самого enum'а.
F2>А переменная типа enum — это просто ссылка на объект.
F2>Соответственно, когда мы делаем state.wait() — мы ждем на мониторе одного объекта,
Да
F2>а когда делаем
F2>
F2> — то это уже нотификация на мониторе другого объекта.
Только Ява тебе такое в ранйтайме сделать не даст.
F2>Правильно ли я понимаю ситуацию? И если да, то как правильно синхронизироваться на мониторе enum'а?
F2>Через класс-обертку?
Простой способ:
Правильный способ:
Простой способ не является рекомендованным, потому что локи предпочтительно делать невидимыми для остальных, тогда как объект класса (даже если сам класс private) может утечь вовне. Предосторожность тут, конечно, на 99.9999% избыточная, но если есть возможность сделать правильно, почему бы и нет.
Нельзя
F2>Насколько я понимаю, в джаве элементы enum'а — это объекты этого самого enum'а.
F2>А переменная типа enum — это просто ссылка на объект.
F2>Соответственно, когда мы делаем state.wait() — мы ждем на мониторе одного объекта,
Да
F2>а когда делаем
F2>
F2>state = State.STATE3;
F2>state.notifyAll();
F2>
F2> — то это уже нотификация на мониторе другого объекта.
Только Ява тебе такое в ранйтайме сделать не даст.
public static void main(String[] args) {
Object b1 = new Object();
Object b2 = new Object();
Object b = b1;
synchronized (b) {
b = b2;
b.notify(); // IllegalMonitorStateException
}
}
F2>Правильно ли я понимаю ситуацию? И если да, то как правильно синхронизироваться на мониторе enum'а?
F2>Через класс-обертку?
Простой способ:
synchronized (Enum.class) {
...
}
Правильный способ:
private volatile State state;
private final Object stateLock = new Object(); // синхронизироваться на этом объекте
Простой способ не является рекомендованным, потому что локи предпочтительно делать невидимыми для остальных, тогда как объект класса (даже если сам класс private) может утечь вовне. Предосторожность тут, конечно, на 99.9999% избыточная, но если есть возможность сделать правильно, почему бы и нет.
Re: Синхронизация через enum-переменную
F2>И вопрос: а можно ли так делать?
Нельзя
F2>Насколько я понимаю, в джаве элементы enum'а — это объекты этого самого enum'а.
F2>А переменная типа enum — это просто ссылка на объект.
F2>Соответственно, когда мы делаем state.wait() — мы ждем на мониторе одного объекта,
Да
F2>а когда делаем
F2>
F2> — то это уже нотификация на мониторе другого объекта.
Только Ява тебе такое в ранйтайме сделать не даст.
F2>Правильно ли я понимаю ситуацию? И если да, то как правильно синхронизироваться на мониторе enum'а?
F2>Через класс-обертку?
Простой способ:
Правильный способ:
Простой способ не является рекомендованным, потому что локи предпочтительно делать невидимыми для остальных, тогда как объект класса (даже если сам класс private) может утечь вовне. Предосторожность тут, конечно, на 99.9999% избыточная, но если есть возможность сделать правильно, почему бы и нет.
Нельзя
F2>Насколько я понимаю, в джаве элементы enum'а — это объекты этого самого enum'а.
F2>А переменная типа enum — это просто ссылка на объект.
F2>Соответственно, когда мы делаем state.wait() — мы ждем на мониторе одного объекта,
Да
F2>а когда делаем
F2>
F2>state = State.STATE3;
F2>state.notifyAll();
F2>
F2> — то это уже нотификация на мониторе другого объекта.
Только Ява тебе такое в ранйтайме сделать не даст.
public static void main(String[] args) {
Object b1 = new Object();
Object b2 = new Object();
Object b = b1;
synchronized (b) {
b = b2;
b.notify(); // IllegalMonitorStateException
}
}
F2>Правильно ли я понимаю ситуацию? И если да, то как правильно синхронизироваться на мониторе enum'а?
F2>Через класс-обертку?
Простой способ:
synchronized (State.class) {
...
}
Правильный способ:
private volatile State state;
private final Object stateLock = new Object(); // синхронизироваться на этом объекте
Простой способ не является рекомендованным, потому что локи предпочтительно делать невидимыми для остальных, тогда как объект класса (даже если сам класс private) может утечь вовне. Предосторожность тут, конечно, на 99.9999% избыточная, но если есть возможность сделать правильно, почему бы и нет.