1. 程式人生 > >多線程學習 公平鎖和非公平鎖

多線程學習 公平鎖和非公平鎖

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.  

  

  每一個優秀的人,都有一段沈默的時光,不抱怨,不訴苦,最後度過那段感動自己的日子。

多線程學習 公平鎖和非公平鎖