2015-06-10 4 views
0

У меня немного уникальная ситуация. Я бы хотел использовать функцию compareAndSet()AtomicReference, но с небольшим количеством поворота.Использование сравнения и набора против нескольких ожидаемых значений с помощью AtomicReference

Обычно вы используете compareAndSet() для сравнения с одним ожидаемым значением, прежде чем вы его действительно измените. В моем случае ожидаемое значение для сравнения может быть одним из многих значений.

Есть ли способ сделать это, используя AtomicReference? Если нет, какие другие методы я должен использовать? Возможно, просто традиционное использование synchronized?

+0

Для сравнения и замены требуется аппаратная поддержка, поэтому я не думаю, что вы можете связать их вместе, чтобы получить нужное поведение. 'synchronized', вероятно, безопаснее. Тем не менее, посмотрите «заблокированный список свободных ссылок», можно спроектировать вокруг проблемы, но это чертовски сложный. – markspace

ответ

2

Я собираюсь предположить, что у вас есть Set ожидаемых значений. В этом случае ...

<T> boolean setIfInExpected(AtomicReference<T> ref, Set<?> expected, T newValue) { 
    while (true) { 
    T current = ref.get(); 
    if (set.contains(current)) { 
     if (atomicReference.compareAndSet(current, newValue)) { 
     return true; 
     } 
    } else { 
     return false; 
    } 
    } 
} 

Это характерно для того, как использует из compareAndSet работы: они работают в цикле, пока AtomicReference не изменяется между get и compareAndSet.

+0

В зависимости от контекста достаточно простого 'return set.contains (current) && atomicReference.compareAndSet (current, newValue);' может быть достаточно, это зависит от того, как соперничество должно быть обработано для конкретного варианта использования. – Holger