카운트다운, CyclicBarrier(순환 울타리)

17050 단어
CountDownLatch():
CountDownLatch는 매우 실용적인 다중 스레드 제어 도구 종류입니다. 이 도구는 보통 스레드 기다림을 제어하는데 사용되며, 어떤 스레드가 카운트다운이 끝날 때까지 기다렸다가 실행을 시작할 수 있습니다.
CountDownLatch의 구조 함수는 현재 이 계수기의 계수 개수인 정수를 매개 변수로 받아들인다.
public CountDownLatch(int count)

다음은 CountDownLatch 사용에 대한 설명입니다.
 1 public class CountDownLatchDemo implements Runnable {
 2 
 3     static CountDownLatch count = new CountDownLatch(10);
 4     static CountDownLatchDemo demo = new CountDownLatchDemo();
 5 
 6     @Override
 7     public void run() {
 8         try {
 9             //      
10             Thread.sleep(new Random().nextInt(10) * 1000);
11             System.out.println("check complete!");
12             count.countDown();
13         } catch (InterruptedException e) {
14             e.printStackTrace();
15         }
16     }
17     //  
18     public static void main(String[] args) throws InterruptedException {
19         ExecutorService exec = Executors.newFixedThreadPool(10);
20         for (int i = 0;i < 10;i++){
21             exec.submit(demo);
22         }
23         //          
24         System.out.println("    :" + Thread.currentThread().getName());
25         count.await();
26         //    
27         System.out.println("    : " + Thread.currentThread().getName());
28         exec.shutdown();
29     }
30 }

결과 출력:
    :main
check complete!
check complete!
check complete!
check complete!
check complete!
check complete!
check complete!
check complete!
check complete!
check complete!
    : main

상기 코드의 세 번째 줄은 CountDownLatch 실례를 생성하고 계수 수량은 10으로 10개의 라인이 임무를 완성해야 하며 CountDownLatch에 있는 라인을 기다려야 계속 실행할 수 있음을 나타낸다.코드 12행에는 CountDownLatch가 사용됩니다.countDown () 방법, 즉 CountDownLatch에 한 라인이 임무를 완성했으니 카운트다운을 줄일 수 있음을 알립니다.25번째 줄에서 CountDownLatch를 사용했습니다.await () 방법, 모든 10개의 작업이 끝난 후에야 주 라인이 계속 실행될 수 있습니다.이 점은 출력 결과에서도 알 수 있듯이 메인 라인은 10개의 라인이 완성된 후에야 계속 집행된다.
 CyclicBarrier():
CyclicBarrier는 멀티스레드 동시 제어 유틸리티입니다.CountDownLatch와 매우 유사하며, 다중 스레드 간의 계수 대기도 실현할 수 있지만, CountDownLatch보다 더욱 복잡하고 강력하다.예를 들어 우리가 계수기를 10으로 설정하면 첫 번째 10개의 라인을 모은 후에 계수기는 0으로 돌아가고 이어서 다음 10개의 라인을 모인다. 이것이 바로 순환 울타리의 의미이다.
CyclicBarrier는 barrier Action으로 매개변수를 수신할 수 있습니다.이barrier Action은 계수기가 계수를 한 번 완성한 후에 시스템이 실행하는 동작입니다.구조 함수는 다음과 같다. 그 중에서 파티스는 계수 총수, 즉 라인의 참여 총수를 나타낸다.
public CyclicBarrier(int parties,Runnable barrierAction)

다음 예제에서는 다음과 같이 설명합니다.
 1 public class CyclicBarrierDemo {
 2 
 3     public static class Soldier implements Runnable{
 4 
 5         private String soldier;
 6         private final CyclicBarrier cyclicBarrier;
 7 
 8         public Soldier(String soldier,CyclicBarrier cyclicBarrier){
 9             this.soldier = soldier;
10             this.cyclicBarrier = cyclicBarrier;
11         }
12 
13         @Override
14         public void run() {
15             try{
16                 //        
17                 cyclicBarrier.await();
18                 doWork();
19                 //          
20                 cyclicBarrier.await();
21             } catch (InterruptedException e) {
22                 e.printStackTrace();
23             } catch (BrokenBarrierException e) {
24                 e.printStackTrace();
25             }
26         }
27         //  
28         void doWork(){
29             try {
30                 Thread.sleep(Math.abs(new Random().nextInt() % 10000));
31             } catch (InterruptedException e) {
32                 e.printStackTrace();
33             }finally {
34                 System.out.println(soldier + "    !");
35             }
36         }
37         //
38         public static class BarrierRun implements Runnable{
39 
40             boolean flag;
41             int N;
42 
43             public BarrierRun(boolean flag,int N){
44                 this.flag = flag;
45                 this.N = N;
46             }
47 
48             @Override
49             public void run() {
50                 if (flag){
51                     System.out.println("  :   " + N + " ,    !");
52                 }else {
53                     System.out.println("  :   " + N + " ,    !");
54                     flag = true;
55                 }
56             }
57         }
58         //  
59         public static void main(String[] args){
60             final int N = 10;
61             Thread[] allSoldier = new Thread[N];
62             boolean flag = false;
63             CyclicBarrier cyclicBarrier = new CyclicBarrier(N,new BarrierRun(flag,N));
64             //
65             System.out.println("    !");
66             for (int i = 0;i < N;i++){
67                 System.out.println("  "+ i + "  !");
68                 allSoldier[i] = new Thread(new Soldier("  "+ i,cyclicBarrier));
69                 allSoldier[i].start();
70             }
71         }
72     }
73 }

위 코드의 63번째 줄은 CyclicBarrier 인스턴스를 만들고 카운터를 10으로 설정하며 카운터가 지표에 도달하면 49줄run() 방법을 실행해야 한다.17행에서는 모든 병사가 집합할 때까지 병사 라인마다 기다린다.집합이 끝난 후, CyclicBarrier의 계수가 완성되었음을 의미하며, 다시 CyclicBarrier를 호출할 때.await () 시 다음 계수가 진행됩니다.18행은 병사의 임무를 모의했다. 한 병사가 임무를 완수하면 코드의 19행은 Cyclic Barrier로 하여금 다음 계수를 시작하게 한다. 이번 계수의 목적은 모든 병사가 임무를 모두 완수했는지 감시하는 것이다.일단 완성되면 49줄의run() 방법이 호출되어 해당하는 정보를 출력합니다.위 코드가 실행되면 출력 결과는 다음과 같습니다.
    !
  0  !
  1  !
  2  !
  3  !
  4  !
  5  !
  6  !
  7  !
  8  !
  9  !
  :   10 ,    !
  1    !
  7    !
  9    !
  0    !
  3    !
  4    !
  6    !
  2    !
  5    !
  8    !
  :   10 ,    ! 

이를 통해 알 수 있듯이 전체적인 작업 과정은 다음과 같다. 먼저 병사 집합을 시작하고 집합이 끝난 후에 집합 완료 통지를 인쇄한다.작업을 시작하고 다음 계수를 진행하며 모든 작업이 완료되면 작업 완료 알림을 인쇄합니다. 
참고:
  CyclicBarrier.await () 방법은 두 가지 이상을 던질 수 있습니다.하나는InterruptedException과BrokenBarrierException이다.InterruptedException은 스레드가 기다리는 과정에서 스레드가 중단되고 대부분의 스레드가 기다리는 방법이 이 이상을 던질 수 있음을 나타낸다.Broken Barrier Exception은 현재의 Cyclic Barrier가 파손되었음을 나타낸다. 시스템이 모든 라인이 다 오기를 기다릴 수 없을 수도 있다. 계속 기다리면 헛수고일 수도 있다. 따라서 이 Cyclic Barrier에서 기다린 다른 라인은 더 이상 기다리지 않고 비정상적인 방식으로 떠날 것이다.
CountDownLatch와 CyclicBarrier의 비교
  ❤ CountDownLatch: 하나의 (또는 여러 개의) 라인으로 다른 N개의 라인이 어떤 일을 완성한 후에야 실행할 수 있습니다.CyclicBarrier: N개의 스레드가 서로 기다립니다. 어떤 스레드가 완성되기 전에 모든 스레드가 기다려야 합니다.
  ❤ CountDownLatch: 일회용;CyclicBarrier: 순환적으로 사용되며 중복될 수 있습니다.
  ❤ CountDownLatch는 AQS 기반,CyclicBarrier 잠금 및 Condition 기반본질적으로 모두 volatile과 CAS에 의존하여 이루어진 것이다.
 
참고: 갈일명 곽초 편저:
전재 대상:https://www.cnblogs.com/Joe-Go/p/9700768.html

좋은 웹페이지 즐겨찾기