基于AtomicBoolean实现的简易锁

package cn.mn.app.ls;

import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.LockSupport;
/**
 * 先进先出锁
 * 公平锁,不可重入
 * locked  记录锁状态,被占用为true,未被任何
 *         线程占用为false,AtomicBoolean 确保线程安全性
 * waiters 线程队列,先进入队列的线程优先获取锁,确保公平性
 * exusiveOwnThread 占有锁的线程
 * 获取锁: 自旋 检查条件如果对列的head是其他线程,或者当前线
 * 		      程但是锁被其他线程占有了,则挂起,如果中断醒来,
 * 		      撤销中断,记录中断状态等待获取到锁后补上中断。获取
 * 		      到锁后结束自旋,设置当前线程为占有锁的线程,在线程
 *        队列移除线程,如果被中断过则补上中断。
 * 释放锁: 如果当前线程不是占有锁的线程抛出异常,如果是,设置
 *        锁的状态为false,唤醒队列的head节点线程。
 * @author WQ
 *
 */
public class FIFOLock {
	private AtomicBoolean locked=new AtomicBoolean(false);
	private Queue<Thread> waiters=new ConcurrentLinkedQueue<Thread>();
	private transient Thread exusiveOwnThread;
	public void lock(){
		boolean wasInterrupted=false;
		Thread current=Thread.currentThread();
		waiters.add(current);
		while(waiters.peek()!=current || !locked.compareAndSet(false, true)){
			LockSupport.park(current);
			if(Thread.interrupted())
				wasInterrupted=true;
		}
		exusiveOwnThread=current;
		waiters.remove();
		if(wasInterrupted)
			current.interrupt();
	}
	
	public void unlock(){
		if(exusiveOwnThread!=Thread.currentThread())
			throw new IllegalMonitorStateException();
		locked.set(false);;
		LockSupport.unpark(waiters.peek());
	}
}

猜你喜欢

转载自blog.csdn.net/liangwenmail/article/details/82222959