Parallele Programmierung (3IB)
=> Grundlage: Hettel und Tran (2016, Kap. 7)
compare-and-set unabhängig von Javajava.util.concurrent.atomic: atomare Skalare (AtomicInteger, AtomicLong, AtomicBoolean), atomare Double und Float, beliebige atomare Funktionenvolatile immer atomarObwohl sie wie (atomare) Instruktionen aussehen mögen, sind Increment (++-Operator) und Decrement (---Operator) keine atomaren Instruktionen.
recht ineffizient (mglw. hoher Anteil an gegenseitigem Ausschluss)
Compare-and-Swap ist eine atomare Instruktion, die von den meisten Rechnerarchitekturen bereitgestellt wird.
Threadsicheres Inkrement mit cas ohne Erfordernis für gegenseitigen Ausschluss:
AtomicBoolean, AtomicInteger, AtomicLongdouble und floatgibt es nicht: “You can also hold floats using Float.floatToIntBits and Float.intBitstoFloat conversions, and doubles using Double.doubleToLongBits and Double.longBitsToDouble conversions.”1
public AtomicFloat(float initialValue) {
this.bits = new AtomicInteger(Float.floatToIntBits(initialValue));
}
public final boolean compareAndSet(float expect, float update) {
return this.bits.compareAndSet(Float.floatToIntBits(expect),
Float.floatToIntBits(update));
}
public final void set(float newValue) {
this.bits.set(Float.floatToIntBits(newValue));
}
public final float get() {
return Float.intBitsToFloat(this.bits.get());
}Atomic*: updateAndGetpublic final long updateAndGet(LongUnaryOperator updateFunction)
public final int updateAndGet(IntUnaryOperator updateFunction)
@FunctionalInterface
public interface LongUnaryOperator {
long applyAsLong(long operand);
}
@FunctionalInterface
public interface IntUnaryOperator {
int applyAsInt(int operand);
}
var i = new AtomicInteger(4711);
i.updateAndGet((in) -> (in * 2));
var l = new AtomicLong(4711);
l.updateAndGet((in) -> (in * 2));pp.05.01-CounterAtomic