2016-10-10 16 views
0

Я пытаюсь понять, как обновляется в getAndIncrement, вот этот фрагмент кода.Java AtomicInteger getAndIncrement() и compareAndSet

public final int getAndIncrement() { 
    for (;;) { 
     int current = get(); 
     int next = current + 1; 
     if (compareAndSet(current, next)) 
      return current; 
    } 
} 

Я понимаю, что compareAndSet Сравнит ли такое же, как значение, хранящееся в регистре текущего значения, если это то же самое, то измените значение в регистре с другой.

Часть, которую я не понимаю, это то, почему она не возвращает next вместо current.

При вводе цикла current задается как int, а current не является опорным значением, поэтому если ток инициализирован как 5, то когда он возвращает ток, должно ли оно быть равно 5? Или, когда он вернется current, current снова вызовет get(), чтобы получить обновленное значение из регистра?

+6

потому что вы вызываете ['getAndIncrement()'] (http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/AtomicInteger.html#getAndIncrement--), который несколько напоминает оператор postincrement ('i ++'). Для описанного поведения существует ['incrementAndGet()'] (http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/AtomicInteger.html#incrementAndGet--) , который напоминает оператор preincrement ('++ i'). – Turing85

+0

Что я спрашиваю, так как «текущий» обновляется как примитив, я вижу только то, что обновляется значение «current»? –

+0

Я не совсем понимаю ваш комментарий. Java имеет значение pass-by-value, поэтому 'current' никогда не будет изменен и, таким образом, в вашем примере' 5' будет возвращен. Отвечает ли это на ваш вопрос? – Turing85

ответ

0

Это улучшает параллелизм.

Если он вернул next, метод должен иметь синхронизированный код, иначе другой поток может изменить значение между его настройкой и возвратом.

Не возвращая next, только фактическая модификация требует синхронизации, постановки ответственности и оптимизации синхронизации в одном месте; compareAndSet(). Когда синхронизация распределяется между методами, гораздо сложнее скоординировать безопасные изменения состояния.

+0

, но ток не является ссылкой, а примитивным значением, текущие вызовы get() снова при выполнении возврата? Здесь я могу видеть только обновленное значение, на которое ссылаются ссылки. –

+0

Можно утверждать, что только один поток может возвращать определенное значение, если 'next' возвращается без синхронизации (и переполняется), так как только один поток сможет успешно вызывать операцию CAS и, следовательно, возвращать определенное значение , Значение 'next' может не возвращать фактическое текущее значение, но это, возможно, не требуется. – Turing85