zoukankan      html  css  js  c++  java
  • Java多线程--公平锁与非公平锁

    上一篇文章介绍了AQS的基本原理,它其实就是一个并发包的基础组件,用来实现各种锁,各种同步组件的。它包含了state变量、加锁线程、等待队列等并发中的核心组件,现在我们来看一下多线程获取锁的顺序问题。

     1   /**
     2      * Creates an instance of {@code ReentrantLock}.
     3      * This is equivalent to using {@code ReentrantLock(false)}.
     4      */
     5     public ReentrantLock() {
     6         sync = new NonfairSync();
     7     }
     8 
     9     /**
    10      * Creates an instance of {@code ReentrantLock} with the
    11      * given fairness policy.
    12      *
    13      * @param fair {@code true} if this lock should use a fair ordering policy
    14      */
    15     public ReentrantLock(boolean fair) {
    16         sync = fair ? new FairSync() : new NonfairSync();
    17     }
    ReentrantLock有两个构造参数,一个有参,一个无参,默认的无参相当于有参数的false。
     1      /**
     2          * Performs non-fair tryLock.  tryAcquire is implemented in
     3          * subclasses, but both need nonfair try for trylock method.
     4          */
     5         final boolean nonfairTryAcquire(int acquires) {
     6             final Thread current = Thread.currentThread();
     7             int c = getState();
     8             if (c == 0) {
     9                 if (compareAndSetState(0, acquires)) {
    10                     setExclusiveOwnerThread(current);
    11                     return true;
    12                 }
    13             }
    14             else if (current == getExclusiveOwnerThread()) {
    15                 int nextc = c + acquires;
    16                 if (nextc < 0) // overflow
    17                     throw new Error("Maximum lock count exceeded");
    18                 setState(nextc);
    19                 return true;
    20             }
    21             return false;
    22         }

     如果为参数为false为非公平锁,非公平锁获取锁的方式为如果当前没有线程占有锁,当前线程直接通过cas指令占有锁,管他等待队列,就算自己排在队尾也是这样

     1        /**
     2          * Fair version of tryAcquire.  Don't grant access unless
     3          * recursive call or no waiters or is first.
     4          */
     5         protected final boolean tryAcquire(int acquires) {
     6             final Thread current = Thread.currentThread();
     7             int c = getState();
     8             if (c == 0) {
     9                 if (!hasQueuedPredecessors() &&
    10                     compareAndSetState(0, acquires)) {
    11                     setExclusiveOwnerThread(current);
    12                     return true;
    13                 }
    14             }
    15             else if (current == getExclusiveOwnerThread()) {
    16                 int nextc = c + acquires;
    17                 if (nextc < 0)
    18                     throw new Error("Maximum lock count exceeded");
    19                 setState(nextc);
    20                 return true;
    21             }
    22             return false;
    23         }        
     1 public final boolean hasQueuedPredecessors() {
     2         // The correctness of this depends on head being initialized
     3         // before tail and on head.next being accurate if the current
     4         // thread is first in queue.
     5         Node t = tail; // Read fields in reverse initialization order
     6         Node h = head;
     7         Node s;
     8         return h != t &&
     9             ((s = h.next) == null || s.thread != Thread.currentThread());
    10     }

    如果为参数为true为公平锁,公平锁获取锁的方式为如果当前线程是等待队列的第一个或者等待队列为空或为当前占有线程,则通过cas指令设置state为1或增加。公平锁加锁的线程全部是按照先来后到的顺序,依次进入等待队列中排队的,不会盲目的胡乱抢占加锁。

     
  • 相关阅读:
    如何一次插入多条记录的SQL语句
    oracle 创建联合主键语句
    02-36 支持向量回归
    245 第三篇:Django-路由控制
    244 第二篇:Django简介
    243 第一篇:自定义Web框架
    242 第一篇:Http协议详细介绍
    02-34 非线性支持向量机(鸢尾花分类)+自定义数据分类
    241 第一篇:web应用
    240 vue学习【第6篇】:vue之导入Bootstrap
  • 原文地址:https://www.cnblogs.com/ding-dang/p/11145404.html
Copyright © 2011-2022 走看看