1. 程式人生 > >Semaphore的使用之-公平與非公平訊號量的測試

Semaphore的使用之-公平與非公平訊號量的測試

有些時候,獲得許可的順序與執行緒啟動的順序有關,這時訊號量就要分為公平與非公平的。

所謂的公平訊號量是獲得鎖的順序與執行緒啟動順序有關,但不代表100%地獲得訊號量,僅僅是在概率上能得到保證。而非公平訊號量就是無關的了。

建立測試用的專案semaphoreFairTest,類MyService.java程式碼如下:

package com.yc.semephore_2;

import java.util.concurrent.Semaphore;

public class MyService {
	private boolean isFair = false;
	private Semaphore semaphore = new Semaphore(1, isFair);
	
	public void testFair(){
		try {
			semaphore.acquire();
			System.out.println( "正在執行的執行緒Thread-Name:" + Thread.currentThread().getName());
		} catch (InterruptedException e) {
			e.printStackTrace();
		} finally{
			semaphore.release();
		}
	}
}
執行緒類ThreadA.java如下:
package com.yc.semephore_2;

public class ThreadA extends Thread{
	private MyService service;
	
	public ThreadA(MyService service){
		super();
		this.service = service;
	}
	
	@Override
	public void run() {
		System.out.println( "Thread-Name:" + this.getName() + "啟動了!");
		service.testFair();
	}

}

測試類SemaphoreFairTest.java如下:

package com.yc.semephore_2;

public class SemaphoreFairTest {
	public static void main(String[] args) {
		MyService service = new MyService();
		ThreadA firstThread = new ThreadA(service);
		firstThread.start();
		
		ThreadA[] thds = new ThreadA[4];
		for(int i = 0; i < thds.length; i ++){
			thds[i] = new ThreadA(service);
			thds[i].start();
		}
		
	}
}

當Semaphore初始化引數boolean fair的值為 false時,得到如下某一次測試結果:
Thread-Name:Thread-1啟動了!
Thread-Name:Thread-0啟動了!
正在執行的執行緒Thread-Name:Thread-0
正在執行的執行緒Thread-Name:Thread-1
Thread-Name:Thread-2啟動了!
正在執行的執行緒Thread-Name:Thread-2
Thread-Name:Thread-3啟動了!
正在執行的執行緒Thread-Name:Thread-3
Thread-Name:Thread-4啟動了!
正在執行的執行緒Thread-Name:Thread-4

當Semaphore初始化引數boolean fair的值為 true是,得到如下某一次測試結果:
Thread-Name:Thread-0啟動了!
Thread-Name:Thread-3啟動了!
Thread-Name:Thread-4啟動了!
Thread-Name:Thread-2啟動了!
Thread-Name:Thread-1啟動了!
正在執行的執行緒Thread-Name:Thread-0
正在執行的執行緒Thread-Name:Thread-3
正在執行的執行緒Thread-Name:Thread-4
正在執行的執行緒Thread-Name:Thread-2
正在執行的執行緒Thread-Name:Thread-1

從上面的兩次實驗結果來看:

公平訊號量的效果是執行緒的啟動順序與呼叫Semaphore.acquire()順序有關,即先啟動的執行緒優先得到許可。

非公平訊號量的效果是與執行緒的啟動順序與呼叫Semaphore.acquire()順序無關,也就是說先啟動的執行緒並不一定先獲得許可。