(二)線程同步_6---修改鎖的競爭原則

修改鎖的競爭原則

ReentrantLock和ReentrantReadWriteLock的構造函數都有一個Boolean型參數fairness,默認爲false,該參數用來控制改變鎖的競爭原則,即兩種競爭模式java

  • non-fair mode:當多個線程等待獲取鎖時,jvm隨機選擇其中一個線程獲取鎖對象,訪問臨界區;
  • fair-mode:在該模式下,jvm會選擇等待時間最長的線程來獲取鎖;

然而tryLock()方法能夠不時線程睡眠,因此若是是使用tryLock()那麼fairness參數將無效,不會有任何影響;dom

下面例子中使用一個屬性做爲實驗,看在兩種模式下的不一樣表現;jvm

動手實驗

(1)建立PrintQueueide

public class PrintQueue {
    private final Lock queueLock=new ReentrantLock(true);

    public void printJob(Object document) {
        queueLock.lock();
        try {
            Long duration=(long)(Math.random()*10000);
            System.out.printf("%s:PrintQueue: Printing a Job during %d seconds\n",
                    Thread.currentThread().getName(),(duration/1000));
            Thread.sleep(duration);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            queueLock.unlock();
        }
        //-------------
        queueLock.lock();
        try {
            Long duration=(long)(Math.random()*10000);
            System.out.printf("%s:PrintQueue: Printing a Job during %d seconds\n",
                    Thread.currentThread().getName(),(duration/1000));
            Thread.sleep(duration);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            queueLock.unlock();
        }
    }
}
(2)建立Job

public class Job implements Runnable {
    private PrintQueue printQueue;

    public Job(PrintQueue printQueue) {
        this.printQueue = printQueue;
    }

    @Override
    public void run() {
        System.out.printf("%s: Going to print a document\n", Thread.currentThread().getName());
        printQueue.printJob(new Object());
        System.out.printf("%s: The document has been printed\n",Thread.currentThread().getName());
    }

    public static void main(String[] args) {
       PrintQueue printQueue=new PrintQueue();
        Thread thread[]=new Thread[10];
        for (int i=0; i<10; i++){
            thread[i]=new Thread(new Job(printQueue),"Thread "+ i);
        }

        for (int i=0; i<10; i++){
            thread[i].start();
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

一次運行結果:

Thread 0: Going to print a document
Thread 0:PrintQueue: Printing a Job during 0 seconds
Thread 1: Going to print a document
Thread 2: Going to print a document
Thread 3: Going to print a document
Thread 4: Going to print a document
Thread 5: Going to print a document
Thread 6: Going to print a document
Thread 7: Going to print a document
Thread 1:PrintQueue: Printing a Job during 9 seconds
Thread 8: Going to print a document
Thread 9: Going to print a document
Thread 2:PrintQueue: Printing a Job during 8 seconds
Thread 3:PrintQueue: Printing a Job during 1 seconds
Thread 4:PrintQueue: Printing a Job during 7 seconds
Thread 5:PrintQueue: Printing a Job during 4 seconds
Thread 6:PrintQueue: Printing a Job during 9 seconds
Thread 7:PrintQueue: Printing a Job during 8 seconds
Thread 0:PrintQueue: Printing a Job during 0 seconds
Thread 8:PrintQueue: Printing a Job during 0 seconds
Thread 0: The document has been printed
當fairness設置爲true,當printJob()方法執行再次獲取Lock時,此時應該是Thread-1等待的時間最長,也是應該最早獲取鎖的線程,如上輸出結果;若是將fairness設置爲false,在此觀察輸出結果,多運行幾回發現結果都不同;函數

要點

瞭解fairness參數的做用this

相關文章
相關標籤/搜索