AQS结构图

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;

/**
 * @author Kevin @date 2017-12-19
 * 
 * 自定义独占锁实现。
 *
 */
public class MyLock implements Lock {
	
	/**
	 * @author Kevin
	 * 
	 * 利用同步器AbstractQueuedSynchronizer这一线程安全的基础组件,完成独占锁的实现。
	 * AbstractQueuedSynchronizer作为 同步基础组件 而设计,这也是设计者的初衷,让程序员利用它完成更多同步工作。
	 * 
	 * AbstractQueuedSynchronizer实现分析:(来自于并发编程的艺术一书)
	 * 	AQS中的静态内部类Node(当前线程和等待状态等信息、前后驱节点信息)是构成同步队列的基础。
	 * 
	 * 同步队列是遵循FIFO,入队进队尾,这个过程需要借助CAS保证线程安全,因此提供了compareAndSetTail()的方法。
	 * 获取到同步状态的首节点在释放同步状态的同时,后继节点将会获取同步状态并且置位首节点。此过程是不需要CAS操作的,
	 * 因为获取同步状态的只有一个线程,不存在问题。
	 * 
	 *
	 */
	private static class Sync extends AbstractQueuedSynchronizer {
		
		/**
		 * 
		 */
		private static final long serialVersionUID = 1L;

		//是否处于占用状态
		@Override
		protected boolean isHeldExclusively() {
			return getState() == 1;
		}
		
		//当状态为0 的时候获取锁
		@Override
		protected boolean tryAcquire(int arg) {
			if(compareAndSetState(0, 1)){
				setExclusiveOwnerThread(Thread.currentThread());
				return true;
			}
			return false;
		}
		
		//释放锁,将状态设置为 0 
		@Override
		protected boolean tryRelease(int arg) {
			if(getState() == 0)
				throw new IllegalMonitorStateException();
			setExclusiveOwnerThread(null);
			setState(0);
			return true;
		}
		
		Condition newCondition(){
			
			return new ConditionObject();
		}
	}

	private final Sync sync = new Sync();
	
	@Override
	public void lock() {
		sync.acquire(1);
	}

	@Override
	public void lockInterruptibly() throws InterruptedException {
		sync.acquireInterruptibly(1);
	}

	@Override
	public boolean tryLock() {
		return sync.tryAcquire(1);
	}

	@Override
	public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
		return sync.tryAcquireNanos(1, unit.toNanos(time));
	}

	@Override
	public void unlock() {
		sync.release(1);
	}

	@Override
	public Condition newCondition() {
		return sync.newCondition();
	}
	
	public boolean isLocked(){
		return sync.isHeldExclusively();
	}
	
	public boolean hasQueuedThreads(){
		return sync.hasQueuedThreads();
	}
	
}

posted on 2018-04-04 09:51  菜码农先生  阅读(113)  评论(0编辑  收藏  举报