Semaphore同時個数制御

3432 ワード


Semaphoreは、リソースが同時にアクセスできる数を制御し、acquire()はライセンスを取得し、なければ待機し、release()はライセンスを解放します.たとえばWindowsで共有ファイルの最大クライアントアクセス数を設定できます.
またリエントランドロックReentrantLockもこの機能を実現できるが,実装上のコードも複雑である.
 
SemaPhoreは、スレッド同期の数を制御する信号量オブジェクトであり、信号量の個数を定義することができる.たとえば、3つのスレッドを同期して共有リソースに入ることしか許可されず、他のスレッドはブロックされています.
例えば、トイレには3つの穴があり、10人が入っていて、毎回3つしか入っていません.信号灯で実現.
その利点は、反発ロックを使用すると、異常が発生するとロックが解放されず、ロックは自分でしか解放されない他のスレッドによって起動できることです.例えば、一人でトイレに行って、反発ロックを採用すれば、その人がトイレに倒れたとき、このトイレは使用できません.信号を使って反発すれば、不動産業者がトイレを開けて人を助けて使うことができます.
 
// 
Semaphore(int permits) 
          //  Semaphore。
Semaphore(int permits, boolean fair) 
          //  Semaphore。

 
次のDemoは、7つのスレッドを起動し、毎回3つのスレッドだけを動作させ、他のスレッドをブロックします.3つのスレッドの動作時間は10000以内の乱数です.
 
package tags;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import

java.util.concurrent.Semaphore;

public class TestSemaphore {

	public static void	main(String[] args) {

		ExecutorService exec = Executors.newCachedThreadPool();

		//  5 
		final Semaphore sp = new	Semaphore(3);

		//  10 
		for (int index = 0; index < 7; index++) {
			Runnable rb = new Runnable() {
				public void run() {
					try {
						sp.acquire(); //  
						
						System.out.println(" " + Thread.currentThread().getName() +   
	                            " , " + (3-sp.availablePermits()) + " ");  
							//availablePermits()   。
						
						Thread.sleep((long) (Math.random() * 10000));						
						System.out.println(" " + Thread.currentThread().getName() + " "); 
						
						sp.release();//  , 
						
						 System.out.println(" " + Thread.currentThread().getName() +   
			                     " , " + (3-sp.availablePermits()) + " ");  
					} catch (InterruptedException e) {
					}
				}
			};
			exec.execute(rb);
		}

		//  
		exec.shutdown();
	}
}

結果:
 
スレッドpool-1-thread-2が入り、現在2つの同時
スレッドpool-1-thread-3が入り、現在3つの同時
スレッドpool-1-thread-1が入り、現在2つの同時
スレッドpool-1-thread-3が離れる
スレッドpool-1-thread-4が入り、現在3つの同時
スレッドpool-1-thread-3が離れ、現在3つの同時実行があります
スレッドpool-1-thread-2が離れる
スレッドpool-1-thread-2が離れ、現在2つの同時実行があります
スレッドpool-1-thread-7が入り、現在3つの同時
スレッドpool-1-thread-1が離れる
スレッドpool-1-thread-5が入り、現在3つの同時
スレッドpool-1-thread-1はすでに離れており、現在3つの同時実行があります.
スレッドpool-1-thread-4が離れる
スレッドpool-1-thread-4が離れ、現在2つの同時実行があります
スレッドpool-1-thread-6が入り、現在3つの同時
スレッドpool-1-thread-7が離れる
スレッドpool-1-thread-7はすでに離れており、現在2つの同時実行がある.
スレッドpool-1-thread-6が離れる
スレッドpool-1-thread-6が離れ、現在1つの同時実行があります.
スレッドpool-1-thread-5が離れる
スレッドpool-1-thread-5はすでに離れており、現在は0個の同時実行があります.
 
参照:http://blog.csdn.net/lb85858585/article/details/7273561
JDK: http://www.cjsdn.net/doc/jdk50/java/util/concurrent/Semaphore.html#availablePermits()