Как слабыйCompareAndSet может дать сбой, если он реализован точно так же, как CompareAndSet? - PullRequest
43 голосов
/ 14 марта 2010

(обратите внимание, что этот вопрос не о CAS, а о "Может произойти сбой" Javadoc).

Единственное отличие Javadoc между этими двумя методами из класса AtomicInteger состоит в том, что weakCompareAndSet содержит комментарий: "Может произойти сбой внезапно" .

Теперь, если мое заклинание не обмануло мои глаза, оба метода выглядят одинаково:

public final boolean compareAndSet(int expect, int update) {
  return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}

/* ...
 * May fail spuriously.
 */
public final boolean weakCompareAndSet(int expect, int update) {
  return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}

Так что я понимаю, что «май» не означает «должен», но тогда почему бы нам всем не начать добавлять это в нашу кодовую базу:

public void doIt() {
    a();
}

/**
 * May fail spuriously
 */
public void weakDoIt() {
    a();
}

Я действительно запутался с этим weakCompareAndSet () , который, кажется, делает то же самое, что и compareAndSet () , но который "может произойти сбой", в то время как другой не может.

Очевидно, что "слабый" и "ложный сбой" в некотором роде связаны с упорядочением "происходит до", но я все еще очень смущен этими двумя методами AtomicInteger (и AtomicLong и т. Д.): , потому что, по-видимому, они вызывают точно такой же unsafe.compareAndSwapInt метод .

Я особенно запутался в том, что AtomicInteger был представлен в Java 1.5, поэтому после изменения модели памяти Java (так что, очевидно, это не то, что "могло бы внезапно завершиться неудачей в 1.4" , но чье поведение изменено на "не должно произойти внезапно через 1,5" ).

Ответы [ 2 ]

19 голосов
/ 14 марта 2010

Существует разница между реализацией и спецификацией ...

В то время как в конкретной реализации может быть мало смысла в предоставлении различных реализаций, будущие реализации, возможно, на другом оборудовании могут захотеть. Вопрос о том, имеет ли этот метод свой вес в API, является спорным.

Также методы weak не имеют порядка , произошедшего до . Не weak версии ведут себя как volatile поля.

1 голос
/ 12 сентября 2015

Просто немного поиграем, если бы ваш вопрос был

Как слабый DoIt может терпеть неудачу, если он реализован точно так же, как doIt?

вот ответ!

public void doIt() {
    a();
}

/**
 * May fail spuriously
 */
public void weakDoIt() {
    a();
}

void a(){
    if(Thread.currentThread().getStackTrace()[2].toString().contains("weakDoIt"))
        System.out.println("I will fail spuriously!");
    else System.out.println("I won't fail spuriously!");
}
...