ReentrantLock 公平锁VS非公平锁

杀马特。学长 韩版系。学妹 提交于 2020-04-05 20:48:13

ReentrantLock

先来看看底层源码,只实现了Lock接口和序列化接口,其中还有3个内部类,3个内部类的实现

public class ReentrantLock implements Lock, java.io.Serializable

看看它的构造方法

   public ReentrantLock() {
       // 默认实现非公平锁
        sync = new NonfairSync();
    }
    
     public ReentrantLock(boolean fair) {
         // 根据你传的值判断实现公平锁还是非公平锁
        sync = fair ? new FairSync() : new NonfairSync();
    }

字段

// 持有一个Sync实例,既构造方法中生成公平锁或非公平锁实例
private final Sync sync;

1.lock()

在NonfairSync中

final void lock() {
    		// 判断当前state值是否为0,,如果为0则修改为1,并且将线程置为当前线程
            if (compareAndSetState(0, 1))
                setExclusiveOwnerThread(Thread.currentThread());
            else
                // 尝试获取锁
                acquire(1);
        }

trylock

 final boolean nonfairTryAcquire(int acquires) {
            final Thread current = Thread.currentThread();e
     		// 获取同步状态值
            int c = getState();
     		// 为0表示当前资源无人占用
            if (c == 0) {
                // 再次比较判断是否有人中途占用了资源,如果没有就将state设置为1,并且将线程设置为当前线程
                if (compareAndSetState(0, acquires)) {
                    setExclusiveOwnerThread(current);
                    return true;
                }
            }
     		// 判断是否是同一个线程
            else if (current == getExclusiveOwnerThread()) {
                // 可重入锁加1
                int nextc = c + acquires;
                if (nextc < 0) // overflow
                    throw new Error("Maximum lock count exceeded");
                setState(nextc);
                return true;
            }
            return false;
        }

在FairSync中

final void lock() {
    		// 尝试获取锁
            acquire(1);
        }

tryLock()

// 查询是否有任一线程等待时间长于当前线程 
protected final boolean tryAcquire(int acquires) {
            final Thread current = Thread.currentThread();
            int c = getState();
            if (c == 0) {
                // 与非公平锁的主要差别就这hasQueuPreDecessors(),查询是否有其他线程等待时间更长
                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;
        }

hasQueuedPredecessors

  public final boolean hasQueuedPredecessors() {
        // The correctness of this depends on head being initialized
        // before tail and on head.next being accurate if the current
        // thread is first in queue.
        Node t = tail; // Read fields in reverse initialization order
        Node h = head;
        Node s;
      	// 只有当这里返回false的时候,tryLock方法才能进入并获取锁
      	// 如果当前线程之前有排队的进程则返回true
      	// 如果当前线程位于队列的开头或者队列为空,则返回false
        return h != t &&
            ((s = h.next) == null || s.thread != Thread.currentThread());
    }

附录

1.Sync

// 实现了AQS接口 
abstract static class Sync extends AbstractQueuedSynchronizer {
        private static final long serialVersionUID = -5179523762034025860L;
		/**
         * 子类实现
         */
        abstract void lock();

   		/**
         * NonFair子类的tryLock方法会调用此方法
         */
        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;
        }

        protected final boolean tryRelease(int releases) {
            int c = getState() - releases;
            if (Thread.currentThread() != getExclusiveOwnerThread())
                throw new IllegalMonitorStateException();
            boolean free = false;
            if (c == 0) {
                free = true;
                setExclusiveOwnerThread(null);
            }
            setState(c);
            return free;
        }

        protected final boolean isHeldExclusively() {
            // While we must in general read state before owner,
            // we don't need to do so to check if current thread is owner
            return getExclusiveOwnerThread() == Thread.currentThread();
        }

        final ConditionObject newCondition() {
            return new ConditionObject();
        }

        // Methods relayed from outer class

        final Thread getOwner() {
            return getState() == 0 ? null : getExclusiveOwnerThread();
        }

        final int getHoldCount() {
            return isHeldExclusively() ? getState() : 0;
        }

        final boolean isLocked() {
            return getState() != 0;
        }

        /**
         * Reconstitutes the instance from a stream (that is, deserializes it).
         */
        private void readObject(java.io.ObjectInputStream s)
            throws java.io.IOException, ClassNotFoundException {
            s.defaultReadObject();
            setState(0); // reset to unlocked state
        }
    }

2.NonfairSync

static final class NonfairSync extends Sync {
        private static final long serialVersionUID = 7316153563782823691L;

        /**
         * Performs lock.  Try immediate barge, backing up to normal
         * acquire on failure.
         */
        final void lock() {
            if (compareAndSetState(0, 1))
                setExclusiveOwnerThread(Thread.currentThread());
            else
                acquire(1);
        }

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

3.FairSync

static final class FairSync extends Sync {
        private static final long serialVersionUID = -3000897897090466540L;

        final void lock() {
            acquire(1);
        }

        /**
         * Fair version of tryAcquire.  Don't grant access unless
         * recursive call or no waiters or is first.
         */
        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;
        }
    }
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!