AtomicInteger и операции сравнения - PullRequest
0 голосов
/ 21 сентября 2018

Я пытаюсь использовать переменную AtomicInteger в качестве блокировки.Итак, интересно, является ли код, размещенный ниже, потокобезопасным.Я знаю, что incrementAndGet () является атомарной операцией.Но я не уверен, будет ли последующая операция «==» также атомарной (что, если значение будет увеличено до 2, к тому времени, когда я сделаю сравнение).Так что постите этот вопрос, чтобы услышать ваши мысли.

private AtomicInteger count = new AtomicInteger(0); //Shared variable
private final int max = 1;

if(count.incrementAndGet() == max) {
  //Do something
}

1 Ответ

0 голосов
/ 21 сентября 2018

Поскольку incrementAndGet() является атомарной операцией, максимум один поток получит 1 для результата (до тех пор, пока для AtomicInteger не установлено значение меньше 1).Это гарантируется AtomicInteger.Хотя фактическое сравнение составляет , а не часть этой атомарной операции, только поток, получивший 1, попадет в блок if.Это потому, что сравнение сравнивает два значения типа int: результат incrementAndGet()) и max.AtomicInteger не играет в этом никакой роли, поскольку примитив int не меняет своего значения при изменении внутреннего состояния count.tl; dr: Ваш код эквивалентен:

final int val = count.incrementAndGet(); // (it makes no difference if val is not 'final`)
if (val == max) {
    // ...
}

Java предоставляет множество других способов обеспечения безопасности потоков ( Lock , CountDownLatch , Семафор, ...), но поскольку вы ссылаетесь на AtomicInteger, я считаю, что AtomicInteger.compareAndSet () более точно соответствует тому, что вы спрашивали:

if (count.compareAndSet(0, 1)) {
    // executed if count == 0
    count.set(0);
}
...