多線程學習 公平鎖和非公平鎖
阿新 • • 發佈:2018-08-18
ava print anr 控制臺 finall 個數 rac 每一個 count()
公平與非公平鎖:鎖lock分為 公平鎖和非公平鎖,公平鎖表示現場獲取鎖的順序是按照線程加鎖的順序來分配的,
即先來先得的FIFO先進先出順序。而非公平鎖就是一種獲取鎖的搶占機制,是隨機獲得的鎖的,和公平鎖不一樣的就是先來
不一定先得到鎖,這個方式可能造成某些線程一直拿不到鎖。
首先來驗證公平鎖:創建service方法,使用lock進行鎖定。
public class Service { private ReentrantLock lock; public Service(boolean isFair){ super(); System.out.println(isFair); lock=new ReentrantLock(isFair); } public void serviceMethod(String str){ try { lock.lock(); if("a".equals(str)){//將啟動的線程全部阻塞在此 try { Thread.sleep(2000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } System.out.println("ThreadName= "+Thread.currentThread().getName()+" 獲得了鎖"); } finally { lock.unlock(); } } }
然後運行驗證:
public class Run { public static void main(String[] args) throws InterruptedException { fair(true); // fair(false); } public static void fair(boolean isFair) throws InterruptedException{ final Service service=new Service(isFair); new Thread(new Runnable() { public void run() { System.out.println("第一個線程,起阻塞後面線程作用"); service.serviceMethod("a"); } }).start(); Thread.sleep(500); Runnable runnable=new Runnable() { public void run() { System.out.println("線程 "+Thread.currentThread().getName()+" 運行了"); service.serviceMethod("b"); } }; Thread [] threads=new Thread[10]; for (int i = 0; i < threads.length; i++) { threads[i]=new Thread(runnable); } for (int i = 0; i < threads.length; i++) { threads[i].start(); } } }
公平鎖控制臺:
true 第一個線程,起阻塞後面線程作用 線程 Thread-1 運行了 線程 Thread-2 運行了 線程 Thread-3 運行了 線程 Thread-4 運行了 線程 Thread-5 運行了 線程 Thread-6 運行了 線程 Thread-7 運行了 線程 Thread-8 運行了 線程 Thread-9 運行了 線程 Thread-10 運行了 ThreadName= Thread-0 獲得了鎖 ThreadName= Thread-1 獲得了鎖 ThreadName= Thread-2 獲得了鎖 ThreadName= Thread-3 獲得了鎖 ThreadName= Thread-4 獲得了鎖 ThreadName= Thread-5 獲得了鎖 ThreadName= Thread-7 獲得了鎖 ThreadName= Thread-6 獲得了鎖 ThreadName= Thread-8 獲得了鎖 ThreadName= Thread-9 獲得了鎖 ThreadName= Thread-10 獲得了鎖
可以發現,控制臺是有序的,其中0線程是為了方便觀看,特意增加,將所有的線程阻塞在此。
非公平鎖的控制臺:
false 第一個線程,起阻塞後面線程作用 線程 Thread-1 運行了 線程 Thread-3 運行了 線程 Thread-2 運行了 線程 Thread-4 運行了 線程 Thread-5 運行了 線程 Thread-10 運行了 線程 Thread-9 運行了 線程 Thread-8 運行了 線程 Thread-7 運行了 線程 Thread-6 運行了 ThreadName= Thread-0 獲得了鎖 ThreadName= Thread-2 獲得了鎖 ThreadName= Thread-3 獲得了鎖 ThreadName= Thread-1 獲得了鎖 ThreadName= Thread-4 獲得了鎖 ThreadName= Thread-5 獲得了鎖 ThreadName= Thread-10 獲得了鎖 ThreadName= Thread-9 獲得了鎖 ThreadName= Thread-8 獲得了鎖 ThreadName= Thread-6 獲得了鎖 ThreadName= Thread-7 獲得了鎖
可以發現,先進但不是先獲得鎖,是無序的。ReentranReentrantLock默認是非公平的。
順便留下幾個lock中常用的方法:
lock.getHoldCount(); 查詢當前線程保持此鎖定的個數。也就是調用lock()方法的次數。
lock.getQueuelength();返回正在等待獲取次鎖定的線程估計數。例如五個線程,1一個線程正在制定await()方法,name咋動用此方法後返回4.
lock.getWaitQueueLength(Condition,condition); 返回等待與此鎖定相關的給定條件Condition的線程估計數。比如有五個線程執行同一個condition對象的await()方法,
調用此方法之後返回5.
每一個優秀的人,都有一段沈默的時光,不抱怨,不訴苦,最後度過那段感動自己的日子。
多線程學習 公平鎖和非公平鎖