У меня есть фрагмент кода, который выглядит следующим образом:
Фрагмент A:
class Creature {
private static long numCreated;
public Creature() {
synchronized (Creature.class) {
numCreated++;
}
}
public static long numCreated() {
return numCreated;
}
}
Насколько я понимаю, после прочтения numCreated
не синхронизируется, если Thread-A создает Creature
в 13:00, а Thread-B читает numCreated ()
в 14:00, numCreated ()
вполне возможно, вернул либо 0, либо 1 (даже если Thread-A завершил инициализацию объекта в 1.05pm).
Итак, я добавил synchronized
в numCreated ()
:
Snippet B :
class Creature {
private static long numCreated;
public Creature() {
synchronized (Creature.class) {
numCreated++;
}
}
public static synchronized long numCreated() { // add "synchronized"
return numCreated;
}
}
и все в порядке, за исключением того, что я думал, если я изменю его to Фрагмент C , правильно ли синхронизирована переменная numCreated
?
Фрагмент C:
class Creature {
private static volatile long numCreated; // add "volatile"
public Creature() {
synchronized (Creature.class) {
numCreated++;
}
}
public static long numCreated() { // remove "synchronized"
return numCreated;
}
}
С фрагментом C гарантировано ли, что как только Thread-A завершает создание объекта в 13:05, вызов Thread-B numCreated ()
обязательно вернет 1
?
PS: Я понимаю, что в реальной ситуации я вероятно, использовал бы AtomicLong
, но это для учебных целей