File tree Expand file tree Collapse file tree 1 file changed +70
-0
lines changed Expand file tree Collapse file tree 1 file changed +70
-0
lines changed Original file line number Diff line number Diff line change @@ -224,5 +224,75 @@ ReentrantLock 分为**公平锁**和**非公平锁**,可以通过构造方法
224
224
}
225
225
```
226
226
227
+ 还要一个重要的区别是在尝试获取锁时` tryAcquire(arg) ` ,非公平锁是不需要判断队列中是否还有其他线程,也是直接尝试获取锁:
228
+
229
+ ``` java
230
+ final boolean nonfairTryAcquire(int acquires) {
231
+ final Thread current = Thread . currentThread();
232
+ int c = getState();
233
+ if (c == 0 ) {
234
+ // 没有 !hasQueuedPredecessors() 判断
235
+ if (compareAndSetState(0 , acquires)) {
236
+ setExclusiveOwnerThread(current);
237
+ return true ;
238
+ }
239
+ }
240
+ else if (current == getExclusiveOwnerThread()) {
241
+ int nextc = c + acquires;
242
+ if (nextc < 0 ) // overflow
243
+ throw new Error (" Maximum lock count exceeded" );
244
+ setState(nextc);
245
+ return true ;
246
+ }
247
+ return false ;
248
+ }
249
+ ```
250
+
251
+ ## 释放锁
252
+
253
+ 公平锁和非公平锁的释放流程都是一样的:
254
+
255
+ ``` java
256
+ public void unlock() {
257
+ sync. release(1 );
258
+ }
259
+
260
+ public final boolean release(int arg) {
261
+ if (tryRelease(arg)) {
262
+ Node h = head;
263
+ if (h != null && h. waitStatus != 0 )
264
+ unparkSuccessor(h);
265
+ return true ;
266
+ }
267
+ return false ;
268
+ }
269
+
270
+ // 尝试释放锁
271
+ protected final boolean tryRelease(int releases) {
272
+ int c = getState() - releases;
273
+ if (Thread . currentThread() != getExclusiveOwnerThread())
274
+ throw new IllegalMonitorStateException ();
275
+ boolean free = false ;
276
+ if (c == 0 ) {
277
+ free = true ;
278
+ setExclusiveOwnerThread(null );
279
+ }
280
+ setState(c);
281
+ return free;
282
+ }
283
+ ```
284
+
285
+ 首先会判断当前线程是否为获得锁的线程,由于是重入锁所以需要将 ` state ` 减到 0 才认为完全释放锁。
286
+
287
+ 释放之后需要调用 ` unparkSuccessor(h) ` 来唤醒被挂起的线程。
288
+
289
+
290
+ ## 总结
291
+
292
+ 由于公平锁需要关心队列的情况,得按照队列里的先后顺序来获取锁(会造成大量的线程上下文切换),而非公平锁则没有这个逻辑。
293
+
294
+ 所以也就能解释非公平锁的效率会被公平锁更高。
295
+
296
+
227
297
228
298
You can’t perform that action at this time.
0 commit comments