1. 程式人生 > >Java執行緒之semaphore和Exchanger

Java執行緒之semaphore和Exchanger

Semaphore是Java執行緒的一個計數訊號量。我們可用於多執行緒的併發訪問控制。

就像我們常見的執行緒池,資料庫連線池就可以使用Semaphore進行邏輯的實現。Semaphore中我們就介紹兩個最常用的兩個方法。

acquire() 從Semaphore獲取許可,如果計數不小於0,就說明還有可用的許可,那麼執行緒就可以成功獲取許可,執行。如果沒有許可

      了,那麼這個方法就會一直阻塞到成功獲取許可。預設獲取一個許可。

release()   釋放許可。當我們使用完畢之後,一定要記得釋放許可,以便讓其它執行緒可以繼續獲取許可訪問資源。

示例:

public class SemaphoreTest {

	public static void main(String[] args) {

		Semaphore semaphore = new Semaphore(3, true);    // 建立訊號量,第二個引數表示是公平的還是非公平的
		for(int i=1;i<=5;i++){
			new Thread(new Producer(semaphore), "執行緒"+i).start();
		}
	}
}
class Producer implements Runnable{
	private Semaphore semaphore;
	public Producer(Semaphore semaphore) {
		this.semaphore = semaphore;
	}
	
	@Override
	public void run() {
		try {
			semaphore.acquire();    // 這裡如果不能獲得許可,就會一直阻塞
		} catch (InterruptedException e) {}
		System.out.println(Thread.currentThread().getName()+"producer");
		semaphore.release();           // 釋放許可
	}
}	

Exchanger 可以在兩個執行緒之間交換資料,但是也僅僅允許兩個執行緒。

Exchanger有一個exchange()方法,可以接收要交換的資料。當一個執行緒呼叫exchange方法之後,就會阻塞,一直到另一個執行緒也

呼叫exchange方法,這時兩個執行緒的資料進行交換後,兩個執行緒就得以繼續執行了。

方法示例:

// 建立Exchanger例項
Exchanger<String> exchanger = new Exchanger<>();

// 執行緒1呼叫Exchanger例項的exchange方法
exchanger.exchange("執行緒1資料");

// 執行緒2呼叫Exchanger例項的exchange方法

exchanger.exchange("執行緒2資料");


 只有當兩個執行緒都呼叫同一個Exchanger例項的exchange方法後,執行緒才能得以繼續執行。