セマフォ、セマフォは、一般に、接続プーリング、オブジェクトプーリング、スレッドプール、などのような特定のリソースにアクセスできるスレッドの数を制限するために使用されます。その中で、あなたは、データベース接続プールと最も馴染みがあり、同時に、それは同時に、もちろん、前に各接続が解除され、接続プールを使用して複数のスレッドを許可する必要があり、他のスレッドを使用することを許可されていません。
セマフォは1に初期化し、それはそれだけで、ほとんどの1つは相互排他ロックとして機能することができ、利用可能許可有するように使用されています。つの利用可能な許可、またはゼロの許可利用可能:それは2つのだけの状態を持っているので、これはより一般的に、バイナリセマフォとして知られています。このように使用すると、バイナリセマフォは、「ロック」は、所有者以外のスレッド(セマフォは、所有権の概念を持っていないとして)によって解放することができ、(多くのLock実装とは異なり)性質を持っています。これは、デッドロックの回復などの一部の特殊な状況で役立ちます。
1.LocKケース
パブリック クラスLockTest { 公共 静的 ボイドメイン(文字列[]引数){ ロックロックは = 新新)(ReentrantLockのを、
//Lock.lock()コメントロック、それが解放されるように取得するには何のロックが存在しないため、エラーになります )(lock.unlock; //Lock.unlock()、スレッドはロックによって保持されなければならない前に、そうでない場合、例外がスローされます }
スレッド"メイン" java.lang.IllegalMonitorStateExceptionの例外
java.util.concurrent.locks.ReentrantLock $ Sync.tryRelease(ReentrantLock.java:155)で
java.util.concurrent.locks.AbstractQueuedSynchronizer.releaseで(AbstractQueuedSynchronizer.java:1260 )
java.util.concurrent.locks.ReentrantLock.unlock(ReentrantLock.java:460)で
LockTest.mainで(LockTest.java:12)
2.Semaphoreケース
パブリック クラスセマフォ{ 公共 静的 ボイドメイン(文字列[]引数){ セマフォセマフォ = 新しい新しいセマフォ(1); //初期化ライセンス するSystem.out.println( "使用可能なライセンスの数:" + semaphore.availablePermitsを()); semaphore.release(); System.out.println( "使用可能なライセンスの数:" + semaphore.availablePermits()); }
結果は以下の通りであります:
利用可能なライセンスの数は、1つの
利用可能なライセンスの数は、 2
結果は、次の2つの質問を示しています。
1.リリースを()を呼び出す前にスレッドをで例外をスローしませんでした、コール取得する必要はありません()。
2.当社は、利用可能なパーミットの数に増加が見ますが、我々の意図は、相互排他ロックの目的を達成するために、その唯一のライセンスを確保することです。
これは、セマフォの別の使用である:デッドロック回復デッドロック回復
我々は実験を行います。
クラス WorkThread2が拡張スレッドを{ プライベートセマフォsemaphore1、semaphore2。 公共WorkThread2(セマフォsemaphore1、セマフォsemaphore2){ この .semaphore1 = semaphore1。 この .semaphore2 = semaphore2。 } 公共 のボイドreleaseSemaphore2(){ System.out.println(にThread.currentThread()のgetId()。 +」释放Semaphore2" ); semaphore2.release(); } 公共 のボイドの実行(){ しようと{ semaphore1.acquire(); // 先获取Semaphore1 のSystem.out.println(にThread.currentThread()のgetId()+」获得Semaphore1" 。); TimeUnit.SECONDS.sleepは( 5); // WorkThread1は、最初の取得のために5秒間待ちSemaphore2 semaphore2.acquire(); // 取得Semaphore2 するSystem.out.println(にThread.currentThread()のgetId()+ "Semaphore2を取得します" ) ; } キャッチ(InterruptedExceptionある電子){ e.printStackTrace(); } } } クラス WorkThread1が拡張スレッドを{ プライベートセマフォsemaphore1、semaphore2。 公共WorkThread1(セマフォsemaphore1、セマフォsemaphore2){ この .semaphore1 = semaphore1。 この .semaphore2 = semaphore2。 } 公共 のボイドの実行(){ しようと{ semaphore2.acquire(); // 最初の取得Semaphore2 のSystem.out.println(にThread.currentThread()のgetId()+ "Semaphore2を得ます。" ); TimeUnit.SECONDS.sleep( 5); // WorkThread1が最初に取得させ、5秒待ってSemaphore1 semaphore1.acquire(); // Semaphore1取得 するSystem.out.println(にThread.currentThread()のgetIdを()+ "Semaphore1を取得します"。); } キャッチ(InterruptedExceptionある電子){ e.printStackTrace(); } } } パブリック クラスSemphoreTest { 公共 静的 ボイドメイン(文字列[]引数)がスローInterruptedExceptionあるが{ セマフォsemaphore1 = 新しいセマフォ(1 ); Semaphore2セマフォ = 新しい新しいセマフォ(1 ); 新新WorkThread1(semaphore1、semaphore2).start(); 新新WorkThread2(semaphore1、semaphore2).start(); // この時点では、デッドロックに巻き込まれている(それはライブロックと言うことができます)
// WorkThread1はsemaphore1許可を保持し、要求許可semaphore2 // WorkThread2はsemaphore2許可を保持し、要求許可semaphore1 // TimeUnit.SECONDS.sleep(10);
// // かメインスレッドでsemaphore1、semaphore2、決意デッドロック
//するSystem.out.println( "===レリーズ信号=="); // semaphore1.release(); // semaphore2.release(); } }
出力:
取得Semaphore2
取得Semaphore1
我々は最終的なリリースのコードブロックを開くとき:
取得Semaphore2 取得Semaphore1 === ==リリース信号 取得Semaphore1 取得Semaphore2
だから、非所有者デッドロック回復スレッドによって達成されていますが、ロックを使用している場合は不可能であり、あなたがしよう二つのオブジェクトに2つのセマフォコードロックを置くことができます。明らかに、また最初のあなたは、このロックオブジェクトを持っている必要があり、したがって、非所有者のスレッドが(以前にロックを所有していない)他のスレッドロックオブジェクトを解放することができない、ロックを解除するためにLock.unlock()を使用し、フロントを検証しました。
================================================== ========================
あなたはあなたにこの記事が参考に見つけた場合、あなたができる[ 懸念私 ]または[ 親指 ]
私たちは、鹿を追いかけるように、道路インフラとのことを願って、と私は同じ優雅な鹿をしたいです
================================================== ========================