blob: b1ade56c5c11bd53e8770f816303d847decfc28d [file] [log] [blame]
/*
* Copyright 1999-2011 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.dubbo.common.utils;
import java.util.concurrent.atomic.AtomicInteger;
/**
* AtomicPositiveInteger
*
* @author william.liangf
* @author ding.lid
*/
public class AtomicPositiveInteger extends Number {
private static final long serialVersionUID = -3038533876489105940L;
private final AtomicInteger i;
public AtomicPositiveInteger() {
i = new AtomicInteger();
}
public AtomicPositiveInteger(int initialValue) {
i = new AtomicInteger(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;
}
}
}
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;
}
}
}
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;
}
}
}
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;
}
}
}
public final int get() {
return i.get();
}
public final void set(int newValue) {
if (newValue < 0) {
throw new IllegalArgumentException("new value " + newValue + " < 0");
}
i.set(newValue);
}
public final int getAndSet(int newValue) {
if (newValue < 0) {
throw new IllegalArgumentException("new value " + newValue + " < 0");
}
return i.getAndSet(newValue);
}
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;
}
}
}
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;
}
}
}
public final boolean compareAndSet(int expect, int update) {
if (update < 0) {
throw new IllegalArgumentException("update value " + update + " < 0");
}
return i.compareAndSet(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);
}
public byte byteValue() {
return i.byteValue();
}
public short shortValue() {
return i.shortValue();
}
public int intValue() {
return i.intValue();
}
public long longValue() {
return i.longValue();
}
public float floatValue() {
return i.floatValue();
}
public double doubleValue() {
return i.doubleValue();
}
public String toString() {
return i.toString();
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((i == null) ? 0 : i.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (getClass() != obj.getClass()) return false;
AtomicPositiveInteger other = (AtomicPositiveInteger) obj;
if (i == null) {
if (other.i != null) return false;
} else if (!i.equals(other.i)) return false;
return true;
}
}