2012-03-26 6 views
3

Es gibt einen Hinweis am Ende des atomics package summary, die besagt:hinzufügen Atom Doppel

... können Sie auch halten floatsFloat.floatToIntBits und Float.intBitstoFloat Konvertierungen verwenden und doubles mit Double.doubleToLongBits und Double.longBitsToDouble Konvertierungen.

Natürlich kann man nicht nur diese Werte addieren sich so was das Äquivalent zu dem Atom addAndGet für einen double Wert wäre.

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

Sie können davon ausgehen, ich sehr hart versuchen synchronized nicht zu verwenden.

Antwort

4

Guava bietet AtomicDouble, und die Verwendung dieser ist wahrscheinlich die einfachste Sache zu tun, anstatt es selbst rollen ...

Das heißt, es innen mit einem Wrapper um AtomicLong implementiert ist, können Sie die Umsetzung von addAndGet sehen here; es ist im Grunde

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; 
    } 
} 

die ist wirklich die einzige Möglichkeit, es zu tun, ohne mit der Montage zu tun.

Vollständige Offenlegung: Ich arbeite an Guava.

+0

Ah ja! Ich kann sehen, wie das der einzige Weg wäre, ohne zu JNI und Assembler zu gehen. Könnten Sie bitte hier die Lösung als Code zur Vollständigkeit posten? Nur das 'addAndGet' wäre ausreichend. – OldCurmudgeon

+0

Lösung veröffentlicht. –

+0

Obwohl Hunger in der Theorie ein Problem sein kann, denke ich, dass es in der Praxis nicht wirklich vorkommt. – biziclop