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 = private static final AtomicIntegerFieldUpdater<AbstractReferenceCountedByteBuf> refCntUpdater =
AtomicIntegerFieldUpdater.newUpdater(AbstractReferenceCountedByteBuf.class, "refCnt"); AtomicIntegerFieldUpdater.newUpdater(AbstractReferenceCountedByteBuf.class, "refCnt");
private volatile int refCnt = 1; private volatile int refCnt;
protected AbstractReferenceCountedByteBuf(int maxCapacity) { protected AbstractReferenceCountedByteBuf(int maxCapacity) {
super(maxCapacity); super(maxCapacity);
refCntUpdater.set(this, 1);
} }
@Override @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 * An unsafe operation intended for use by a subclass that sets the reference count of the buffer directly
*/ */
protected final void setRefCnt(int refCnt) { protected final void setRefCnt(int refCnt) {
this.refCnt = refCnt; refCntUpdater.set(this, refCnt);
} }
@Override @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 * An unsafe operation intended for use by a subclass that sets the reference count of the buffer directly
*/ */
protected final void setRefCnt(int refCnt) { protected final void setRefCnt(int refCnt) {
this.refCnt = refCnt; refCntUpdater.set(this, refCnt);
} }
@Override @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_INIT = 0;
public static final int WORKER_STATE_STARTED = 1; public static final int WORKER_STATE_STARTED = 1;
public static final int WORKER_STATE_SHUTDOWN = 2; public static final int WORKER_STATE_SHUTDOWN = 2;
@SuppressWarnings({ "unused", "FieldMayBeFinal", "RedundantFieldInitialization" }) @SuppressWarnings({ "unused", "FieldMayBeFinal" })
private volatile int workerState = WORKER_STATE_INIT; // 0 - init, 1 - started, 2 - shut down private volatile int workerState; // 0 - init, 1 - started, 2 - shut down
private final long tickDuration; private final long tickDuration;
private final HashedWheelBucket[] wheel; private final HashedWheelBucket[] wheel;