獨占鎖 -- 鎖在一個時間點只能被一個線程鎖占有。根據鎖的獲取機制,它又劃分為“公平鎖”和“非公平鎖”。公平鎖,是按照通過CLH等待線程按照先來先得的規則,公平的獲取鎖;而非公平鎖,則當線程要獲取鎖時,它會無視CLH等待隊列而直接獲取鎖。獨占鎖的典型實例子是ReentrantLock,此外,Reen... ...
一、公平鎖
1、為什麼有公平鎖
CPU在調度線程的時候是在等待隊列里隨機挑選一個線程,由於這種隨機性所以是無法保證線程先到先得的(synchronized控制的鎖就是這種非公平鎖)。但這樣就會產生饑餓現象,即有些線程(優先順序較低的線程)可能永遠也無法獲取cpu的執行權,優先順序高的線程會不斷的強制它的資源。那麼如何解決饑餓問題呢,這就需要公平鎖了。
產生饑餓的另一個原因是:某個線程占據資源不釋放,那其他需要該資源的線程只能處於無限等待中。在這裡我們主要解決第一種饑餓問題。
2、什麼是公平鎖
公平鎖可以保證線程按照時間的先後順序執行,避免饑餓現象的產生。但公平鎖的效率比較地,因為要實現順序執行,需要維護一個有序隊列。
二、公平鎖的使用
JDK1.5為我們提供了實習公平鎖的方式,創建公平鎖的構造函數是:
java.util.concurrent.locks.ReentrantLock
public ReentrantLock(boolean fair) { sync = fair ? new FairSync() : new NonfairSync(); }
通過判斷fair的值來決定重入鎖(ReentrantLock)是使用公平鎖 FairSync 還是非公平鎖 NonfairSync 。
公平鎖Demo
package com.jalja.base.threadTest; import java.util.concurrent.locks.ReentrantLock; public class LockFairTest implements Runnable{ //創建公平鎖 private static ReentrantLock lock=new ReentrantLock(true); public void run() { while(true){ lock.lock(); try{ System.out.println(Thread.currentThread().getName()+"獲得鎖"); }finally{ lock.unlock(); } } } public static void main(String[] args) { LockFairTest lft=new LockFairTest(); Thread th1=new Thread(lft); Thread th2=new Thread(lft); th1.start(); th2.start(); } }
執行結果:
Thread-1獲得鎖 Thread-0獲得鎖 Thread-1獲得鎖 Thread-0獲得鎖 Thread-1獲得鎖 Thread-0獲得鎖 Thread-1獲得鎖 Thread-0獲得鎖 Thread-1獲得鎖 Thread-0獲得鎖 Thread-1獲得鎖 Thread-0獲得鎖 Thread-1獲得鎖 Thread-0獲得鎖 Thread-1獲得鎖 Thread-0獲得鎖
這是截取的部分執行結果,分析結果可看出兩個線程是交替執行的,幾乎不會出現同一個線程連續執行多次。