AtomicInteger против синхронизированных методов получения / установки - PullRequest
5 голосов
/ 22 марта 2012

Этот класс поточно-ориентирован?

Можно ли увидеть противоречивые значения?Допустим, изначально значение a равно 80. Поток 1 вызывает setA(100) и входит в функцию, но еще не вызывал a.set(100), а поток 2 одновременно вызывает getA().Возможно ли для потока 2 видеть 80?

public class A {
    private AtomicInteger a; 

    public int getA() {
        return a.get()
    }

    public void setA(int newVal){
        a.set(newVal);
    }   
}

Я знаю, что синхронизация гарантирует, что поток 2 видит 100, но не уверен с AtomicInteger.

Ответы [ 2 ]

10 голосов
/ 22 марта 2012

Является ли этот класс поточно-ориентированным?

Да, это так.

Поток 1 вызывает setA (100) и входит в функцию, но еще не сделалВызовите a.set (100), а поток 2 одновременно вызывает getA ().Возможно ли для темы 2 увидеть 80?

Да.Пока код барьера памяти, который синхронизирует энергозависимое поле внутри AtomicInteger, не завершится, условие гонки может показывать 80 или 100.

Поток 1 может даже войти в метод AtomicInteger.set и находиться перед назначением внутреннего поля иТем не менее, 80 может быть возвращено методом get AtomicInteger.get.

Нет никаких гарантий относительно , когда значения будут обновлены в других потоках.Гарантируется, что когда get() завершится, вы получите самое последнее синхронизированное значение, а когда set() завершится, все остальные потоки увидят обновления.

Нет никаких гарантий относительно синхронизация вызовов геттера и сеттера в разных потоках.

1 голос
/ 22 марта 2012

Как отметил @Gray, здесь есть возможность для состояния гонки.

Вызов get, а затем set не является атомарной операцией. Классы Atomic* предлагают безусловную операцию атомарного условного обновления, compareAndSet - ее следует использовать для обеспечения безопасности потока.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...