同時ツールクラス

4413 ワード

CountDownLatch


概要


CountDownLatchでは、1つ以上のスレッドが他のスレッドの完了操作を待つことができます.

シーンの操作


例えば、班長は兵士に防御工事(兵士は1人でも複数でもよい)を建設するように命令し、兵士一人一人が自分の任務を担当し、彼らが完成したら班長に報告し、班長は上級に防御工事の建設が完了したことを報告する.この例では班長が兵士が任務を遂行するのを待っている後、イメージのCountDownLatchの例である.

一般的な方法

  • await():このメソッドスレッド待ちを呼び出す.
  • countDown():このメソッドを呼び出して完了待ちのタスクが完了したら1を減算します(内部カウンタの値は1を減算します).

  • join()メソッドとの比較


    CountDownLatchはjoin()メソッドの機能を実現し,join()メソッドを置き換えることができる.

    CyclicBarrier


    概要


    CyclicBarrierは、スレッドのセットがバリア(同期ポイントとも呼ばれる)に到達するとブロックされ、最後のスレッドがバリアに到達するまでバリアが開き、バリアによってブロックされたスレッドはすべて動作し続けます.

    シーンの操作


    例えば、班長は防御工事を建設する準備をしています.この時、兵士Aが到着し、兵士Bが到着したことを知っています.みんなで建設に行きます.A兵士が到着したら、防御工事を建設することはできません.これがCyclicBarrier(int parties,Runnable barrier Action)のbarrier Actionで、動員後はみんな鶏の血のように仕事をしています.

    一般的な方法

  • int await()は、すべての参加者がこのbarrierでawaitメソッドを呼び出すまで待機します.
  • int await(long timeout,TimeUnit unit)は、すべての参加者がこのバリア上でawaitメソッドを呼び出すまで待機する.
  • int getNumberWaiting()は、バリアで現在待機している参加者の数を返します.
  • int getParties()は、このbarrierの起動を要求する参加者の数を返します.
  • boolean isBroken()は、このバリアが破損しているかどうかを問い合せます.
  • void reset()バリアを初期状態にリセットします.

  • 備考:int await(long timeout,TimeUnit unit)は、待機時間を設定し、上記の例に従って班長が皆さんを10分待って、10分後に兵士が到着しなければ、待たないで、班長と他の兵士は防御工事を建設して、この時班長は話をしないことに注意して、直ちにこの手配があって、遅刻した兵士が到着した後に直接防御工事を建設します.
    public class CyclicBarrierDemo {
    
        static CyclicBarrier c = new CyclicBarrier(2, new A());
    
        public static void main(String[] args) {
    
            new Thread(new Runnable() {
    
                public void run() {
                    try {
                        c.await(1,TimeUnit.SECONDS);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } catch (BrokenBarrierException e) {
                        e.printStackTrace();
                    } catch (TimeoutException e) {
                        e.printStackTrace();
                    }
                    System.out.println(1);
                }
            }).start();
    
            try {
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }            c.await();
    
            } catch (Exception e) {
    
            }
            System.out.println(2);
        }
    
        static class A implements Runnable {
    
            public void run() {
                System.out.println(3);
            }
    
        }
    
    }
    //   3
    

    CountDownLatchとの比較


    CountDownLatchとCyclicBarrierは、スレッド間の待機を実現できますが、それらの側面は異なります.
  • CountDownLatchは、通常、あるスレッドAが複数の他のスレッドがタスクを実行した後に実行されるのを待つために使用される.CyclicBarrierは、一般に、スレッドのセットが互いにある状態まで待機し、その後、スレッドのセットが同時に実行されるために使用されます.
  • CountDownLatchのカウンタは一度しか使用できません.CyclicBarrierのカウンタはreset()メソッドを使用してリセットできます.したがって、CyclicBarrierは、計算にエラーが発生した場合、カウンタをリセットし、スレッドを再実行するなど、より複雑なビジネスシーンを処理することができます.
  • CyclicBarrierはまた、getNumberWaiting法のような他の有用な方法を提供し、CyclicBarrierブロックのスレッド数を得ることができる.isBrokenメソッドは、ブロックされたスレッドが中断されたかどうかを知るために使用されます.たとえば、次のコードが実行されるとtrueが返されます.

  • Semaphore


    概要


    Semaphore(信号量)は、特定のリソースに同時にアクセスするスレッドの数を制御するために使用され、各スレッドを調整することによって、共通のリソースの合理的な使用を保証する.

    シーンの操作


    データベース接続リソースにアクセスするには、30個のスレッドがデータベースにアクセスしますが、データベース接続数は10個しかありません.この場合、10個のスレッドだけが同時にデータベース接続を取得してデータを保存することを制御する必要があります.そうしないと、エラーが発生してデータベース接続を取得できません.

    一般的な方法

  • void acquire():この信号量からライセンスを取得し、ライセンスを提供する前にスレッドをブロックします.そうしないと、スレッドは中断されます.
  • void release():許可を解放し、信号量に戻す.
  • int availablePermits():この信号量で現在使用可能なライセンス数を返します.
  • boolean hasQueuedThreads():取得待ちスレッドがあるかどうかを問い合せます.

  • ロックと


    単一信号量のSemaphoreオブジェクトは、反発ロックの機能を実現することができ、一方のスレッドによって「ロック」が得られ、他方のスレッドによって「ロック」が解放されることができ、これはデッドロック回復の場合に適用することができる.

    Exchanger


    概要


    2つのスレッドは、オブジェクトの同期ポイントを交換できます.各スレッドはexchangeメソッドに入るとオブジェクトを与え、他のスレッドが戻るとオブジェクトを受け入れます.

    シーンの操作


    Exchangerは校正作業にも使用できます.例えば、紙製銀の流れを人工的に電子銀行の流れに入力する必要があります.エラーを避けるために、AB岡二人で入力します.Excelに入力した後、システムはこの2つのExcelをロードし、この2つのExcelデータを校正して、入力が一致しているかどうかを確認します.

    一般的な方法

  • V exchange(Vx)は、他のスレッドがこの交換点に到達するのを待って(中断されない限り)、所定のオブジェクトをスレッドに転送し、スレッドのオブジェクトを受信する.
  • V exchange(Vx,long timeout,TimeUnit unit)は、他のスレッドがこの交換点に到達するのを待って(中断されないか、指定された待機時間を超えない限り)、所定のオブジェクトをスレッドに転送し、スレッドのオブジェクトを受信します.