2015-11-13 7 views
4

Java AtomicInteger предлагает public final boolean compareAndSet(int expect, int update). Если возвращается false, я хотел бы знать, какое значение фактически было в то время, когда сравнение не удалось. Возможно ли это на Java?AtomicInteger.compareAndSet, который возвращает исходное значение, а не boolean

В .Net есть public static int CompareExchange(ref int location1, int value, int comparand), который всегда возвращает исходное значение.

+0

Вам это не нужно –

ответ

1
public int getAndCompareAndSet(AtomicInteger ai, int expected, int update) { 
    while (true) { 
    int old = ai.get(); 
    if (old != expected) { 
     return old; 
    } else if (ai.compareAndSet(old, update)) { 
     return old; 
    } 
    } 
} 

(Этот вид цикла как большинство операций по AtomicInteger реализуются: петли получить, сделать некоторую логику, попробуйте сравнить-и-набор.)

+0

Интересно, что это такое .Net делает внутренне, или если .Net может делать все это атомарно за один раз, что, казалось бы, было бы быстрее. Не уверен, существует ли какая-либо такая операция на уровне машины. –

+1

x86 имеет одну инструкцию для этого: http://x86.renejeschke.de/html/file_module_x86_id_41.html –

+0

(Пожалуйста, проигнорируйте ->) Это не очень атомно. Между 'ai.get()' и 'ai.compareAndSet()' хранимое значение может быть изменено другим потоком. – vanza

0

Этот API не предоставляет такой способ. Более того, реализация Oracle использует sun.misc.Unsafe для выполнения собственной операции CAS, и этот тип также не раскрывает ее.

Один из вариантов заключается в том, чтобы просто позвонить get(), если compareAndSetfalse. Однако, к моменту проверки, фактическое значение AtomicInteger могло измениться. Ты не можешь с этим справиться. Это справедливо и для методов Interlocked. Вам нужно будет уточнить, что вы хотите сделать с этим значением, чтобы идти дальше.