Skip to content

Commit

Permalink
Merge pull request apache#348, AtomicPositiveInteger less memory used…
Browse files Browse the repository at this point in the history
… & provides better perf.
  • Loading branch information
fengjiachun authored and chickenlj committed Jun 1, 2018
1 parent e255f54 commit e1171fa
Showing 1 changed file with 28 additions and 72 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,163 +16,120 @@
*/
package com.alibaba.dubbo.common.utils;

import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;

/**
* AtomicPositiveInteger
*/
public class AtomicPositiveInteger extends Number {

private static final long serialVersionUID = -3038533876489105940L;

private final AtomicInteger i;
private static final AtomicIntegerFieldUpdater<AtomicPositiveInteger> indexUpdater =
AtomicIntegerFieldUpdater.newUpdater(AtomicPositiveInteger.class, "index");

@SuppressWarnings("unused")
private volatile int index = 0;

public AtomicPositiveInteger() {
i = new AtomicInteger();
}

public AtomicPositiveInteger(int initialValue) {
i = new AtomicInteger(initialValue);
indexUpdater.set(this, initialValue);
}

public final int getAndIncrement() {
for (; ; ) {
int current = i.get();
int next = (current >= Integer.MAX_VALUE ? 0 : current + 1);
if (i.compareAndSet(current, next)) {
return current;
}
}
return indexUpdater.getAndIncrement(this) & Integer.MAX_VALUE;
}

public final int getAndDecrement() {
for (; ; ) {
int current = i.get();
int next = (current <= 0 ? Integer.MAX_VALUE : current - 1);
if (i.compareAndSet(current, next)) {
return current;
}
}
return indexUpdater.getAndDecrement(this) & Integer.MAX_VALUE;
}

public final int incrementAndGet() {
for (; ; ) {
int current = i.get();
int next = (current >= Integer.MAX_VALUE ? 0 : current + 1);
if (i.compareAndSet(current, next)) {
return next;
}
}
return indexUpdater.incrementAndGet(this) & Integer.MAX_VALUE;
}

public final int decrementAndGet() {
for (; ; ) {
int current = i.get();
int next = (current <= 0 ? Integer.MAX_VALUE : current - 1);
if (i.compareAndSet(current, next)) {
return next;
}
}
return indexUpdater.decrementAndGet(this) & Integer.MAX_VALUE;
}

public final int get() {
return i.get();
return indexUpdater.get(this) & Integer.MAX_VALUE;
}

public final void set(int newValue) {
if (newValue < 0) {
throw new IllegalArgumentException("new value " + newValue + " < 0");
}
i.set(newValue);
indexUpdater.set(this, newValue);
}

public final int getAndSet(int newValue) {
if (newValue < 0) {
throw new IllegalArgumentException("new value " + newValue + " < 0");
}
return i.getAndSet(newValue);
return indexUpdater.getAndSet(this, newValue) & Integer.MAX_VALUE;
}

public final int getAndAdd(int delta) {
if (delta < 0) {
throw new IllegalArgumentException("delta " + delta + " < 0");
}
for (; ; ) {
int current = i.get();
int next = (current >= Integer.MAX_VALUE - delta + 1 ? delta - 1 : current + delta);
if (i.compareAndSet(current, next)) {
return current;
}
}
return indexUpdater.getAndAdd(this, delta) & Integer.MAX_VALUE;
}

public final int addAndGet(int delta) {
if (delta < 0) {
throw new IllegalArgumentException("delta " + delta + " < 0");
}
for (; ; ) {
int current = i.get();
int next = (current >= Integer.MAX_VALUE - delta + 1 ? delta - 1 : current + delta);
if (i.compareAndSet(current, next)) {
return next;
}
}
return indexUpdater.addAndGet(this, delta) & Integer.MAX_VALUE;
}

public final boolean compareAndSet(int expect, int update) {
if (update < 0) {
throw new IllegalArgumentException("update value " + update + " < 0");
}
return i.compareAndSet(expect, update);
return indexUpdater.compareAndSet(this, expect, update);
}

public final boolean weakCompareAndSet(int expect, int update) {
if (update < 0) {
throw new IllegalArgumentException("update value " + update + " < 0");
}
return i.weakCompareAndSet(expect, update);
return indexUpdater.weakCompareAndSet(this, expect, update);
}

@Override
public byte byteValue() {
return i.byteValue();
return (byte) get();
}

@Override
public short shortValue() {
return i.shortValue();
return (short) get();
}

@Override
public int intValue() {
return i.intValue();
return get();
}

@Override
public long longValue() {
return i.longValue();
return (long) get();
}

@Override
public float floatValue() {
return i.floatValue();
return (float) get();
}

@Override
public double doubleValue() {
return i.doubleValue();
return (double) get();
}

@Override
public String toString() {
return i.toString();
return Integer.toString(get());
}

@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + i.hashCode();
result = prime * result + get();
return result;
}

Expand All @@ -181,7 +138,6 @@ public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof AtomicPositiveInteger)) return false;
AtomicPositiveInteger other = (AtomicPositiveInteger) obj;
return i.intValue() == other.i.intValue();
return intValue() == other.intValue();
}

}
}

0 comments on commit e1171fa

Please sign in to comment.