Java 锁机制系列 - Lock接口

   Part 1. Lock接口

  • lock接口的方法和说明

    • lock() 请求一个锁资源,如果锁资源不可用当前线程加入等待队列

    • lockInterruptibly() 请求锁的过程中检测并响应中断标志

    • tryLock() 调用时如果锁资源可用获取返回true,否则返回false

    • tryLock(long time, TimeUnit unit) 在一定时间内获取到锁资源返回true,否则false

    • unlock() 释放锁资源

    • newCondition() 创建一个绑定在锁资源上的condition对象实例

    Part 2. AQS 的抽象方法

    • boolean tryAcquire(int arg);  

    • boolean tryRelease(int arg);

    • int tryAcquireShared(int arg);

    • boolean tryReleaseShared(int arg);

    • boolean isHeldExclusively();

     在编写自定义的锁的时候,在构建tryLock,unlock等方法时,一般会直接使用AQS中的acquire()或者release()方法。例如:

public class ReentrantLock implements Lock, java.io.Serializable {
    private final Sync sync;
    
    public ReentrantLock() {
        sync = new NonfairSync();
    }
    
    public void lock() {
        sync.lock();
    }
    
    public boolean tryLock() {
        return sync.nonfairTryAcquire(1);
    }
    
    abstract static class Sync extends AbstractQueuedSynchronizer {
        abstract void lock();

        final boolean nonfairTryAcquire(int acquires) {
            final Thread current = Thread.currentThread();
            int c = getState();
            if (c == 0) {
                if (compareAndSetState(0, acquires)) {
                    setExclusiveOwnerThread(current);
                    return true;
                }
            }
            else if (current == getExclusiveOwnerThread()) {
                int nextc = c + acquires;
                if (nextc < 0) // overflow
                    throw new Error("Maximum lock count exceeded");
                setState(nextc);
                return true;
            }
            return false;
        }
    }
    
    // 非公平同步器的实现 向ReentrantLock提供tryAcquire方法等
    static final class NonfairSync extends Sync {
    
        final void lock() {
            if (compareAndSetState(0, 1))
                setExclusiveOwnerThread(Thread.currentThread());
            else
                acquire(1);
        }

        protected final boolean tryAcquire(int acquires) {
            return nonfairTryAcquire(acquires);
        }
    }
}

      Part 3. AQS aquire()方法流程

  1. 通过子类tryAcquire方法的CAS操作设置锁资源状态

  2. 步骤1成功则获取锁成功;步骤1失败则加入线程等待队列(CAS添加在队尾)

  3. 执行acquireQueued(一个while true循环)再次尝试获取锁,获取成功返回;获取失败则将线程阻塞(等待),等待release唤醒,继续获取锁

    



你可能感兴趣的:(Lock接口)