AbstractQueuedSynchronizer实现独占锁

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Kevin_King1992/article/details/79813078
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();
    }

}

猜你喜欢

转载自blog.csdn.net/Kevin_King1992/article/details/79813078
今日推荐