Talk about the understanding of java thread (6) -------- ReentrantLock lock release + part of the diagram

      Earlier I talked about the acquisition of unfair locks. I did not say about fair locks. In fact, the difference between fair locks and unfair locks is a problem of preemption. If it is a fair lock, the preemption lock operation will not come up, but first Judge, look at the code

if (c == 0) {
    if (!hasQueuedPredecessors() && compareAndSetState(0, acquires)) {
                    setExclusiveOwnerThread(current);
                    return true;
              }       
}

There is just one more method hasQueuedPredecessors, which means to see if there are waiting threads in the blocked queue. If there are some, just wait and not preempt. If not, it will preempt directly, while non-fair locks are directly preempted. This is The difference between fair lock and unfair lock is almost the same in other places, so there is not much.

       Let's talk about releasing locks. Of course, the ways of releasing locks for fair locks and unfair locks are the same. Let's just start talking, let's go to the code!

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


  public final boolean release(int arg) {
        if (tryRelease(arg)) {   //尝试释放锁,成功的话处理链表头
            Node h = head;
            if (h != null && h.waitStatus != 0)
                unparkSuccessor(h);
            return true;
        }
        return false;
    }

This is the code that ReentrantLock releases the lock, let's look at it a little bit. Show Zhang Tuha

In fact, look at the realization of fair lock release lock in ReentrantLock. 

 protected final boolean tryRelease(int releases) { //releases 目前是1,这个说下哈
            //获取线程的状态,并减一,赋值给新的状态c
            int c = getState() - releases;
            //判断当前线程,如果不是锁的持有者,那你还释放啥?直接报错
            if (Thread.currentThread() != getExclusiveOwnerThread())
                throw new IllegalMonitorStateException();
            boolean free = false;  //定义一个字段,表示释放锁成功
            if (c == 0) {   //状态status恢复成0.就是没有线程持有锁了,释放成功
                free = true; 
                 //设置锁的持有者为空
                setExclusiveOwnerThread(null);
            }
            setState(c); //state 重新复赋值
            return free;
        }

Then it releases the waiting thread and performs the lock gun drill operation.

 private void unparkSuccessor(Node node) {  //注意,传进来的是头结点
         //获取阻塞队列节点的waitStatus,无异常的话应该是-1,插入尾部的时候都把前置节点改成了-1
        int ws = node.waitStatus;
        if (ws < 0)
            compareAndSetWaitStatus(node, ws, 0);  // 修改状态,cas 头结点

         //获取下一个节点,也就是要释放的节点
        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);
    }

This is the main explanation, some of which may not be discussed, but it does not affect the understanding of ReentrantLock. Of course, looking at the code may also be a little dizzy. The two sketches shown below are not well drawn. Forgive me.

AddWaiter method flowchart​​

 

acquireQueued method

Other pictures are still being drawn and will be added later.

        To summarize the processing of this lock (unfair lock), first, CAS optimistic lock locks. If it fails, it enters the blocking queue. If the blocking queue is empty, the blocking queue is initialized and the current thread is added to the end of the blocking queue.

        Determine the front node of the current node. If it is the head node, go directly to grab resources, because the head node is empty, it is added for the convenience of operation. If the front node waitStatus of the current node is 1, delete this node, and loop until the previous node of the current node is set to -1, and then the current thread can be interrupted, which is the main locking process.

If it feels okay, please like it~

no sacifice,no victory~

Guess you like

Origin blog.csdn.net/zsah2011/article/details/108984122