Javaコンカレント(8):コンカレントツールクラス

3739 ワード

一.CountDownLatch


現在のスレッドが他のスレッドの完了操作を待つようにします.
  • CountDownLatchの構造関数は、intタイプのパラメータをカウンタとして受信する.
  • CountDownLatchのcountDown()方法はカウンタの1つを減らすために使用される.
  • CountDownLatchのawait()メソッドは、カウンタがゼロになるまで現在のスレッドをブロックします.

  • 同様に、thread.join()メソッドは、join()メソッドを呼び出すスレッドの実行が完了するまで、現在のスレッドをブロックすることもできる.
    タイムアウト待ち:
  • join(long millis)、join(long millis, int nanos)
  • await(long time, TimeUnit unit)
  • await(long time, TimeUnit unit)は、現在のスレッドをしばらく待たせ、タイムアウト時間が経過すると、現在のスレッドは後続のコードを実行し続け、未完了のスレッドを待たなくなります.

    二.CyclicBarrier


    同期バリア.
    1組のスレッドが1つのバリア(同期ポイントとも呼ばれる)に到達するとブロックされ、最後のスレッドがバリアに到達するまでバリアが開き、バリアによってブロックされたすべてのスレッドが動作し続ける.
  • は、構造関数CyclicBarrier(int parties)を用いて同期バリアを構築し、そのパラメータはバリアが遮断するスレッド数を表す.
  • 各スレッド呼び出しawait()方法は、同期バリアが同期点に到達したと同時に、自分がブロックされていることを同期バリアに伝える.
  • 呼び出しawait()メソッドのスレッド数が設定された値に達すると、バリアが解除され、各スレッドが実行を継続する.

  • より高度なコンストラクション関数CyclicBarrier(int parties, Runnable barrierAction)は、最後のスレッドがバリアに達し、バリアが開かれたときにbarrierActionを優先的に実行し、その後、実行を継続する前にブロックされたスレッドを実行するために使用される.
    CyclicBarrierとCountDownLatchの違い
  • CountDownLatchのカウンタは1回しか使用できませんが、CyclicBarrierのカウンタはreset()メソッドでリセットできます.
  • CyclicBarrierはまた、getNumberWaiting()法のような他の有用な方法を提供し、CyclicBarrierブロックのスレッド数を取得することができる.isBroken()メソッドは、ブロックされたスレッドが中断されたかどうかを知るために使用されます.

  • 三.Semaphore


    Semaphore(信号量)は、特定のリソースに同時にアクセスするスレッドの数を制御するために使用され、各スレッドを調整することによって、共通のリソースの合理的な使用を保証する.
    Semaphoreは、特に共通リソースの限られたアプリケーションシーン、例えばデータベース接続数などのトラフィック制御に使用できます.
  • は、パラメータが利用可能なライセンス数を表す構造関数Semaphore(int permits)によって構成される.
  • スレッドは、semaphore.acquire()を使用してライセンスを取得します.
  • の使用が完了した後、スレッドはsemaphore.release()を使用してライセンスを返します.
  • 残りのライセンス数がゼロより大きい場合にのみ、スレッドはライセンスを取得できます.そうしないと、待機するしかありません.

  • 四.Exchanger


    Exchanger(エクスチェンジ)は、スレッド間のデータ交換に使用できるスレッド間連携用のツールクラスです.
  • Exchangerはexchange()メソッドに同期ポイントを設定します.
  • 最初のスレッドはexchange()メソッド(同期ポイントに到達)まで実行され、2番目のスレッドもexchange()メソッド(同期ポイントに到達)まで待機します.
  • 両方のスレッドが同期ポイントに達した後、両方のスレッドがデータを交換します.
  • public class test {
    
        private static final Exchanger exchanger = new Exchanger<>();
    
        private static ExecutorService threadPool = Executors.newFixedThreadPool(2);
    
        public static void main(String[] args) {
    
            threadPool.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        String a = "aaa";
    
                        System.out.println("begin-a: " + a);
    
                        String a1 = exchanger.exchange(a);
    
                        System.out.println("exchange-a: " + a);
                        System.out.println("exchange-a1: " + a1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
    
            threadPool.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        String b = "bbb";
    
                        System.out.println("begin-b: " + b);
    
                        String b1 = exchanger.exchange(b);
    
                        System.out.println("exchange-b: " + b);
                        System.out.println("exchange-b1: " + b1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
    
            threadPool.shutdown();
        }
    }
    
     :
    begin-a: aaa
    begin-b: bbb
    exchange-b: bbb
    exchange-b1: aaa
    exchange-a: aaa
    exchange-a1: bbb