Javaでは、同期されたキーワードとロックロックを使用して、リソースの同時アクセス制御を実現します。リソースにアクセスするために重要な領域に入ることができます(読み取りロックを除く)。このサブコントロールの主な目的は、同じリソースと同時に複数のスレッドによって引き起こされるデータの矛盾の問題を解決することです。別のシナリオでは、リソースには、プリンタールームの複数のプリンターや同時に使用するための複数のピットなど、同時に使用する複数のコピーがあります。この場合、Javaは別の同時アクセス制御 - リソースの複数のコピーの同時アクセス制御を提供し、今日使用されているセマフォもその1つです。
Javaは、コードシミュレーションを通じて最速の方法で、システム内の潜在的なスレッド安全性の問題を検出できます。ここでは、セマフォ(セマフォ)とカウントダウンラッチ(ロック)が、シミュレーションのためにexecutorService(スレッドプール)で使用されます。主な紹介は次のとおりです。
1。セマフォ
このクラスは、JDK 1.5の後に提供されます
セマフォは、カウントベースのセマフォです。これに基づいて、複数のスレッドがライセンス信号を取得するために競合し、独自のアプリケーションを作成した後に返すしきい値を設定できます。しきい値を超えた後、ライセンス信号に対するスレッドのアプリケーションがブロックされます。セマフォは、データベース接続プールなどのオブジェクトプール、リソースプールなどを構築するために使用できます。また、1のカウントでセマフォを作成し、Mutexロックに似たメカニズムとして使用することもできます。これはバイナリセマフォとも呼ばれ、2つのミューテックス状態を示しています。
2。CountDownLatch
このクラスは、JDK 1.5の後に提供されます。
CountDownLatchクラスは、スレッドを実行する前に他のスレッドがそれぞれの作業を完了するのを待つことができます。たとえば、アプリケーションのメインスレッドは、フレームワークサービスの開始を担当するスレッドがすべてのフレームワークサービスを開始した後に実行したいと考えています。
CountDownLatchはカウンターを介して実装され、カウンターの初期値はスレッドの数です。スレッドが独自のタスクを完了するたびに、カウンター値は1によって減少します。カウンター値が0に達すると、すべてのスレッドがタスクを完了し、ロックを待機するスレッドがタスクの実行を再開できることを意味します。
下の図に示すように:
上記の2つのクラスを組み合わせて使用して、高い並行性をシミュレートする効果を実現できます。次のコードを使用して例を示します。
パッケージモジュール; java.util.concurrent.countdownlatch; Import java.util.concurrent.executorservice; Import java.util.concurrent.executors; Import java.util.concurrent.semaphore; public countexample {// proceation intic int intic intictotal = 5000; //同時に同時に実行されたスレッドの数public static int threadtotal = 200; public static int count = 0; public static void main(string [] args)throws excust {executorservice executorservice = executors.newcachedthreadpool(); //半導体、ここで同時スレッドの数を制御するために使用される最終セマフォセマフォ=新しいセマフォ(threadtotal); //ロック、カウンターの最終的なカウントダウンラッチCountDownLatchの減少を実現できます= new CountDownLatch(clientTotal); for(int i = 0; i <clientTotal; i ++){executorservice.execute(() - > {try {//このメソッドを実行して実行許可を取得します。未発表のライセンスの総数が200を超えない場合、パスを許可します。 } catch(//log.error("exception "、e); } countDownLatch.await(); //スレッドブロック、そしてロック値が0になるまでブロックがリリースされません。Executorservice.shutdown()を実行し続けます。 log.info( "count:{}"、count); } private static void add(){count ++; }}上記の方法に示すように、5000のリクエストがシミュレートされ、200の同時操作は同時に最大200の並行操作です。最終結果を観察し、結果が毎回異なり、期待と矛盾していることを発見します。結果は次のとおりです。
22:18:26.449 [Main] Info Modules.CountExample -Count:4997
22:18:26.449 [Main] Info Modules.CountExample -Count:5000
22:18:26.449 [Main] Info Modules.CountExample -Count:4995
22:18:26.449 [Main] Info Modules.CountExample -Count:4998
最終結論:追加方法はスレッドセーフではありません
次に、ADDメソッドのスレッドの安全性を確保する方法、次のようにADDメソッドを変更します。
private static void add(){count.incrementAndget();}実行結果は次のとおりです。
22:18:26.449 [Main] Info Modules.CountExample -Count:5000
22:18:26.449 [Main] Info Modules.CountExample -Count:5000
22:18:26.449 [Main] Info Modules.CountExample -Count:5000
22:18:26.449 [Main] Info Modules.CountExample -Count:5000
22:18:26.449 [Main] Info Modules.CountExample -Count:5000
22:18:26.449 [Main] Info Modules.CountExample -Count:5000
22:18:26.449 [Main] Info Modules.CountExample -Count:5000
22:18:26.449 [Main] Info Modules.CountExample -Count:5000
最終結論:変更されたメソッドスレッドセーフ
上記はこの記事のすべての内容です。みんなの学習に役立つことを願っています。誰もがwulin.comをもっとサポートすることを願っています。