Use threadsafe setter on Atomic Updaters

Motivation:
The documentation for field updates says:

> Note that the guarantees of the {@code compareAndSet}
> method in this class are weaker than in other atomic classes.
> Because this class cannot ensure that all uses of the field
> are appropriate for purposes of atomic access, it can
> guarantee atomicity only with respect to other invocations of
> {@code compareAndSet} and {@code set} on the same updater.

This implies that volatiles shouldn't use normal assignment; the
updater should set them.

Modifications:
Use setter for field updaters that make use of compareAndSet.

Result:
Concurrency compliant code
This commit is contained in:
Carl Mastrangelo 2017-08-29 23:34:13 -07:00 committed by Norman Maurer
parent cc336ef2f8
commit 7528e5a11e
3 changed files with 6 additions and 5 deletions

View File

@ -30,10 +30,11 @@ public abstract class AbstractReferenceCountedByteBuf extends AbstractByteBuf {
private static final AtomicIntegerFieldUpdater<AbstractReferenceCountedByteBuf> refCntUpdater =
AtomicIntegerFieldUpdater.newUpdater(AbstractReferenceCountedByteBuf.class, "refCnt");
private volatile int refCnt = 1;
private volatile int refCnt;
protected AbstractReferenceCountedByteBuf(int maxCapacity) {
super(maxCapacity);
refCntUpdater.set(this, 1);
}
@Override
@ -45,7 +46,7 @@ public abstract class AbstractReferenceCountedByteBuf extends AbstractByteBuf {
* An unsafe operation intended for use by a subclass that sets the reference count of the buffer directly
*/
protected final void setRefCnt(int refCnt) {
this.refCnt = refCnt;
refCntUpdater.set(this, refCnt);
}
@Override

View File

@ -38,7 +38,7 @@ public abstract class AbstractReferenceCounted implements ReferenceCounted {
* An unsafe operation intended for use by a subclass that sets the reference count of the buffer directly
*/
protected final void setRefCnt(int refCnt) {
this.refCnt = refCnt;
refCntUpdater.set(this, refCnt);
}
@Override

View File

@ -97,8 +97,8 @@ public class HashedWheelTimer implements Timer {
public static final int WORKER_STATE_INIT = 0;
public static final int WORKER_STATE_STARTED = 1;
public static final int WORKER_STATE_SHUTDOWN = 2;
@SuppressWarnings({ "unused", "FieldMayBeFinal", "RedundantFieldInitialization" })
private volatile int workerState = WORKER_STATE_INIT; // 0 - init, 1 - started, 2 - shut down
@SuppressWarnings({ "unused", "FieldMayBeFinal" })
private volatile int workerState; // 0 - init, 1 - started, 2 - shut down
private final long tickDuration;
private final HashedWheelBucket[] wheel;