在 java并发编程学习之显示锁Lock 里有提过公平锁和非公平锁,我们知道他的使用方式,以及非公平锁的性能较高,在AQS源码分析的基础上,我们看看NonfairSync和FairSync的区别在什么地方。
//非公平锁NonfairSync final void lock() { if (compareAndSetState(0, 1)) setExclusiveOwnerThread(Thread.currentThread()); else acquire(1); } //公平锁FairSync final void lock() { acquire(1); }
从源码可以看出,获取锁的时候,非公平锁会先尝试获取,获取不到再调用acquire方法,而公平锁直接调用acquire方法。
////非公平锁NonfairSync protected final boolean tryAcquire(int acquires) { return nonfairTryAcquire(acquires); } 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; }
从源码可以看出,公平锁再尝试获取锁的时候,先判断队列是否有其他节点在等待,没有再获取。而非公平锁直接尝试获取锁。