TwinsLock在同一時刻最多支持兩個線程訪問,超過兩個線程的訪問將被阻塞,這是共享式的訪問
package twinslock;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
public class TwinsLock implements Lock
{
private final Sync sync=new Sync(2);
@Override
public void lockInterruptibly() throws InterruptedException {
sync.acquireSharedInterruptibly(1);
}
@Override
public boolean tryLock() {
sync.tryAcquireShared(1);
return true;
}
@Override
public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
return sync.tryAcquireSharedNanos(1, unit.toNanos(time));
}
@Override
public Condition newCondition() {
return sync.newCondition();
}
private static final class Sync extends AbstractQueuedSynchronizer
{
Sync(int count)
{
if(count<=0)
{
throw new IllegalArgumentException("count must lsrge than zero");
}
setState(count);//設置同步資源數爲count
//當一個線程成功獲取同步狀態時,狀態值減1,釋放同步狀態時狀態值加1,狀態值爲0表示已經有兩個兩個線程獲取同步資源,此時再有其他線程對同步狀態進行獲取將會被阻塞
}
public int tryAcquireShared(int reduceCount)
{
for(;;)
{
int current=getState();
int newCount=current-reduceCount;
if(newCount<0||compareAndSetState(current,newCount))
{//此處的CAS操作很重要,如果此線程計算出newCount之後其他線程改變了隊列同步器的狀態值,原來的newCount已經不是需要正確更新的狀態值了
return newCount;
}
}
}
public boolean tryReleaseShared(int returnCount)
{
for(;;)
{
int current=getState();
int newCount=current+returnCount;
if(compareAndSetState(current,newCount))
{
return true;
}
}
}
public Condition newCondition()
{
return new ConditionObject();
}
}
public void lock()
{
sync.acquireShared(1);
}
public void unlock()
{
sync.releaseShared(1);
}
}