以下代码,没实际意义。
注意以下情况的不同点。
1)volatile 和 Atomic*
* private volatile long unusedAmount = 0;
* private final AtomicLong unusedAmount = new AtomicLong();
* private long unusedAmount = 0;
2)作用域及异常
* nextA1()
* nextA2()
* nextB1()
* nextB2()
注意以下情况的不同点。
1)volatile 和 Atomic*
* private volatile long unusedAmount = 0;
* private final AtomicLong unusedAmount = new AtomicLong();
* private long unusedAmount = 0;
2)作用域及异常
* nextA1()
* nextA2()
* nextB1()
* nextB2()
import java.util.LinkedList;
import java.util.Random;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
* @author : Shi Rongjiu (www.trydofor.com)
*/
public class ThinkingInSync {
private final ReadWriteLock rwLock = new ReentrantReadWriteLock();
private final Lock rLock = rwLock.readLock();
private final Lock wLock = rwLock.writeLock();
// sync
private final LinkedList<Integer> readWriteBox = new LinkedList<Integer>();
private volatile long unusedAmount = 0;
private volatile Integer currentValue = null;
//private final AtomicLong unusedAmount = new AtomicLong(); // 1
//private long unusedAmount = 0; // 2
//
private final Random random = new Random();
private final AtomicInteger counter = new AtomicInteger(0);
public Integer nextA1() throws InterruptedException, TimeoutException {
wLock.lock();
try {
if (readWriteBox.size() <= 0) {
syncLoad();
unusedAmount = readWriteBox.size();
}
currentValue = makeValue();
unusedAmount--;
}
finally {
wLock.unlock();
}
return currentValue;
}
public Integer nextA2() throws InterruptedException, TimeoutException {
wLock.lock();
try {
if (readWriteBox.size() <= 0) {
syncLoad();
unusedAmount = readWriteBox.size();
}
currentValue = makeValue();
unusedAmount--;
return currentValue;
}
finally {
wLock.unlock();
}
}
public Integer nextB1() throws InterruptedException, TimeoutException {
wLock.lock();
try {
if (readWriteBox.size() <= 0) {
syncLoad();
unusedAmount = readWriteBox.size();
}
unusedAmount--;
currentValue = makeValue();
return currentValue;
}
finally {
wLock.unlock();
}
}
public Integer nextB2() throws InterruptedException, TimeoutException {
wLock.lock();
Integer result = null;
long varUnused = unusedAmount;
try {
if (readWriteBox.size() <= 0) {
syncLoad();
varUnused = readWriteBox.size();
}
result = makeValue();
varUnused--;
}
finally {
unusedAmount = varUnused;
currentValue = result;
wLock.unlock();
}
return result;
}
public Integer current() {
rLock.lock();
try {
return currentValue;
}
finally {
rLock.unlock();
}
}
public long remains() {
rLock.lock();
try {
return unusedAmount;
}
finally {
rLock.unlock();
}
}
//-------------------------------
private Integer makeValue() throws InterruptedException, TimeoutException {
randomEvent();
return readWriteBox.isEmpty() ? null : readWriteBox.removeFirst();
}
private int syncLoad() throws InterruptedException, TimeoutException {
int sleep = randomEvent();
readWriteBox.add(counter.incrementAndGet());
int count = 1;
if (sleep % 2 == 0) {
count++;
readWriteBox.add(counter.incrementAndGet());
}
if (sleep % 3 == 0) {
count++;
readWriteBox.add(counter.incrementAndGet());
}
return count;
}
private int randomEvent() throws InterruptedException, TimeoutException {
int sleep = random.nextInt();
if (sleep > 10000) {
Thread.sleep(5000);
throw new TimeoutException();
}
else if (sleep < 100) {
Thread.currentThread().interrupt();
throw new InterruptedException();
}
else {
Thread.sleep(sleep);
}
return sleep;
}
}