ReentrantLock 解析

2019-04-26  本文已影响0人  Wi1ls努力努力再努力
 public ReentrantLock() {
        sync = new NonfairSync();
    }
 public ReentrantLock(boolean fair) {
        sync = fair ? new FairSync() : new NonfairSync();
    }

ReentrantLock 有两种实现,公平锁 FairSync 和非公平锁NonfairSync;

用法

ReentrantLock lock = new ReentrantLock(true/false);

public void lockMethod(){
  lock.lock();
  ...
  lock.unlock();
}

则 lock.lock()和lock.unlock()则为获得锁和释放锁。

@ReentrantLock
public void lock(){
  sync.lock();
}

//以公平锁分析
@FairSync
final void lock(){
  acquire(1);
}

@AbstractQueuedSynchronizer
public final void acquire(int arg){
  if(!tryAcquire(args) &&
    acquireQueued(addWaiter(Node.EXCLUSIVE), arg)){
    selfInterrupt();
  }
}

@FairSync
 protected final boolean tryAcquire(int acquires) {
            //获取当前线程
            final Thread current = Thread.currentThread();
            //获得 volatile state,如果是第一个进来的线程c 为 0,后面进来的线程如果锁还没有释放的话, c 为 1 
            int c = getState();
            if (c == 0) {
                //可以获得锁的线程,并且 CAS 操作设置 state 为 1
                if (!hasQueuedPredecessors() &&
                    compareAndSetState(0, acquires)) {
                    //设置当前获得锁的线程
                    setExclusiveOwnerThread(current);
                    return true;
                }
            }
            else if (current == getExclusiveOwnerThread()) {
                //如果 c 不为 0,说明锁被某个线程获得了,能进这里说明获取锁的线程也是当前线程,说明当前线程 lock()了两次,所以是可重入的,此时将 state 增加
                int nextc = c + acquires;
                if (nextc < 0)
                    throw new Error("Maximum lock count exceeded");
                setState(nextc);
                return true;
            }
            //此时锁被其他线程获得了,则返回 false
            return false;
        }


@AbstractQueuedSynchronizer
//tryAcquire(args) 返回 true 说明获得锁成功,直接跳出去执行方法体
//tryAcquire(args)返回 false,则会进行 acquireQueued(addWaiter(Node.EXCLUSIVE), arg)
public final void acquire(int arg) {
        if (!tryAcquire(arg) &&
            acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
            selfInterrupt();
    }

@AbstractQueuedSynchronizer
//将当前线程入队
private Node addWaiter(Node mode) {
        Node node = new Node(Thread.currentThread(), mode);
        // Try the fast path of enq; backup to full enq on failure
        Node pred = tail;
        if (pred != null) {
            node.prev = pred;
            if (compareAndSetTail(pred, node)) {
                pred.next = node;
                return node;
            }
        }
        enq(node);
        return node;
    }

@AbstractQueuedSynchronizer
//进入死循环等待,每次会获取等待队列的第一个线程,执行tryAcquire(arg)尝试去获得锁,如果获得,则将 status 设置为 1,表示获得了锁
 final boolean acquireQueued(final Node node, int arg) {
        boolean failed = true;
        try {
            boolean interrupted = false;
            for (;;) {
                final Node p = node.predecessor();
                if (p == head && tryAcquire(arg)) {
                    setHead(node);
                    p.next = null; // help GC
                    failed = false;
                    return interrupted;
                }
                if (shouldParkAfterFailedAcquire(p, node) &&
                    parkAndCheckInterrupt())
                    interrupted = true;
            }
        } finally {
            if (failed)
                cancelAcquire(node);
        }
    }

释放锁

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

@AbstractQueuedSynchronizer
 public final boolean release(int arg) {
        //尝试释放锁
        if (tryRelease(arg)) {
            Node h = head;
            if (h != null && h.waitStatus != 0)
                unparkSuccessor(h);
            return true;
        }
        return false;
    }

@ReentrantLock$Sync
protected final boolean tryRelease(int releases) {
            //将锁的信号量-1
            int c = getState() - releases;
            //获得锁的线程和释放锁的线程不是同一个,抛异常
            if (Thread.currentThread() != getExclusiveOwnerThread())
                throw new IllegalMonitorStateException();
            boolean free = false;
            //如果自减后 c==0,则释放锁
            if (c == 0) {
                free = true;
                setExclusiveOwnerThread(null);
            }
            //如果当前线程重入了多次,只把 status-1,线程会继续保留锁
            setState(c);
            return free;
        }


@AbstractQueuedSynchronizer
 private void unparkSuccessor(Node node) {
       
        int ws = node.waitStatus;
        if (ws < 0)
            compareAndSetWaitStatus(node, ws, 0);

         //倒序遍历队伍,找出待唤醒的线程
        Node s = node.next;
        if (s == null || s.waitStatus > 0) {
            s = null;
            for (Node t = tail; t != null && t != node; t = t.prev)
                if (t.waitStatus <= 0)
                    s = t;
        }
        if (s != null)
            //唤醒线程
            LockSupport.unpark(s.thread);
    }

公平锁和非公平锁关键在于

@非公平锁,NonfairSync
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;
        }

@FairSync
protected final boolean tryAcquire(int acquires) {
            final Thread current = Thread.currentThread();
            int c = getState();
            if (c == 0) {
                //如果刚好可以获得锁,并且等待队伍为空才获得锁,否则将自己插入等待队伍队尾
                if (!hasQueuedPredecessors() &&
                    compareAndSetState(0, acquires)) {
                    setExclusiveOwnerThread(current);
                    return true;
                }
            }
            else if (current == getExclusiveOwnerThread()) {
                int nextc = c + acquires;
                if (nextc < 0)
                    throw new Error("Maximum lock count exceeded");
                setState(nextc);
                return true;
            }
            return false;
        }
上一篇下一篇

猜你喜欢

热点阅读