2012-03-26 2 views
3

Существует примечание в конце atomics package summary, который гласит:Добавить атомные двойники

... Вы можете также провести floats с помощью Float.floatToIntBits и Float.intBitstoFloat переходов и doubles с использованием Double.doubleToLongBits и Double.longBitsToDouble преобразования.

Очевидно, что вы не можете просто добавить эти значения вместе с тем, что было бы равносильно атомной addAndGet для значения double.

private AtomicLong sum = new AtomicLong(); 
... 
// This would almost certainly NOT work. 
public long add(double n) { 
    return sum.addAndGet(Double.doubleToLongBits(n)); 
} 

Вы можете предположить, что я очень стараюсь не использовать synchronized.

ответ

4

гуава обеспечивает AtomicDouble, и используя это, вероятно, самое простое, что нужно сделать, а не качение самого ...

Тем не менее, она внутренне реализована с оберткой вокруг AtomicLong, вы можете увидеть их реализацию addAndGethere; это в основном

while (true) { 
    long current = value; 
    double currentVal = longBitsToDouble(current); 
    double nextVal = currentVal + delta; 
    long next = doubleToRawLongBits(nextVal); 
    if (updater.compareAndSet(this, current, next)) { 
    return nextVal; 
    } 
} 

Это действительно единственный способ сделать это, не имея дело со сборкой.

Полное раскрытие информации: Я работаю над Гува.

+0

Ах да! Я вижу, как это будет единственным способом, не перейдя на JNI и ассемблер. Не могли бы вы разместить решение здесь в качестве кода для полноты, пожалуйста? Просто «addAndGet» будет достаточно. – OldCurmudgeon

+0

Решение опубликовано. –

+0

Хотя голодание может быть проблемой в теории здесь, я думаю, это на самом деле не происходит на практике. – biziclop

Смежные вопросы