다 중 스 레 드 002-CountDownlatch 얘 기 하 자.

java.util.concurrent.countDownlatch 는 JDK 1.5 가 제공 하 는 동기 화 보조 클래스 입 니 다.한 그룹 이 다른 스 레 드 에서 작업 을 수행 하기 전에 하나 이상 의 스 레 드 를 기다 릴 수 있 습 니 다.
  Countdown Latch 를 초기 화 할 때 계 수 를 지정 해 야 합 니 다.countDown 방법 을 호출 하여 현재 계수 가 0 에 도달 하기 전에 await 방법 은 계속 막 힐 것 입 니 다.이후 기다 리 는 모든 스 레 드 가 풀 리 고 await 뒤의 작업 도 즉시 실 행 됩 니 다.계수 가 리 셋 되 지 않 기 때문에 이 동작 은 한 번 만 나타 날 수 있 습 니 다.계수 리 셋 이 필요 하 다 면 자바 util.concurrent.cyclicbarrier 를 사용 하 는 것 을 고려 하 십시오.
*8195,Count Downlatch 는 유 니 버 설 동기 화 도구 로 많은 용도 가 있 습 니 다.1 로 초기 화 된 Countdown Latch 는 잠 금 장치 나 입 구 를 간단하게 열 거나 닫 는 데 사용 할 수 있 습 니 다.특정한 스 레 드 에서 countDown 을 호출 하여 입 구 를 열기 전에 모든 await 를 호출 하 는 스 레 드 는 입구 에서 기다 리 고 있 습 니 다.N(N>=1)으로 초기 화 된 Countdown Latch 는 N 개의 스 레 드 가 어떤 작업 을 완료 하기 전에 기다 리 거나,어떤 작업 이 완 료 될 때 까지 기다 릴 수 있 습 니 다.
*8195:Countdown Latch 의 유용 한 기능 은 0 이 되 기 전에 countDown 방법 을 호출 하 는 스 레 드 가 계속 실행 되 는 것 을 막 지 않 습 니 다.await 를 호출 하 는 모든 스 레 드 가 await 뒤의 작업 을 계속 수행 하 는 것 을 막 을 뿐 입 니 다.
Countdown Latch 는 두 가지 전형 적 인 용법 이 있 습 니 다.
4.567917.두 개의 카운터 가 있 는데 하 나 는 시동 신호 이 고 하 나 는 완성 신호 이다
  • 한 문 제 를 N 개 부분 으로 나 누고 실행 해 야 할 N 개 부분 을 Runnable 로 정의 한 다음 모든 Runnable 을 Executor 대기 열 에 추가 합 니 다.모든 N 키 부분 이 완료 되면 기다 리 는 스 레 드 는 await 방법 을 통 해 후속 작업 을 계속 수행 합 니 다

  • 카운터 두 개
    예제 코드:
    public class CountDownLatchTest {
        public static void main(String[] args) throws InterruptedException {
            CountDownLatch startSignal = new CountDownLatch(1);//     
            CountDownLatch doneSignal = new CountDownLatch(N);
    
            for (int i = 0; i < N; ++i) {
                new Thread(new Worker(startSignal, doneSignal)).start();
            }
    
            doSomethingElse();
            startSignal.countDown();//   
            doSomethingElse();
            doneSignal.await();//         
        }
    }
    
    class Worker implements Runnable {
        private final CountDownLatch startSignal;
        private final CountDownLatch doneSignal;
    
        Worker(CountDownLatch startSignal, CountDownLatch doneSignal) {
            this.startSignal = startSignal;
            this.doneSignal = doneSignal;
        }
    
        @Override
        public void run() {
            try {
                startSignal.await();//         
                doWork();
                doneSignal.countDown();
            } catch (InterruptedException ex) {
            }
        }
    
        void doWork() {...}
    }
    

      예제 코드 에서 startSignal 은 선 결 조건 이 고 여기 서 초기 계산 은 1 이 며 간단 한 스위치 입 니 다.예 를 들 어 육 상 경기 에서 100 미터 달리기,신호총 이 울 리 기 전에 선수 들 은 모두 기다 리 고 있다.발령 총 이 울 린 후 운동 선 수 는 경 기 를 시작 하여 마지막 선수 가 결승점 에 도착 할 때 까지 기 다 렸 다가 경기 가 끝났다.
    간단 한 코드 구현:
    package howe.demo.thread.countdown;
    
    import java.util.Random;
    import java.util.concurrent.CountDownLatch;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.TimeUnit;
    
    /**
     * @author liuxinghao
     * @version 1.0 Created on 2014 9 15 
     */
    public class CountDownLatchTest {
        public static void main(String[] args) throws InterruptedException {
            final CountDownLatch begin = new CountDownLatch(1);
            final CountDownLatch end = new CountDownLatch(3);
            final ExecutorService exec = Executors.newFixedThreadPool(3);
    
            for (int index = 0; index < 3; index++) {
                exec.submit(new Runner(index + 1, begin, end));
            }
    
            System.out.println("    。。。");
            System.out.println("  。。。");
            System.out.println(" 。。。");
            begin.countDown();
            end.await();
            System.out.println("    ,    。");
            exec.shutdown();
        }
    }
    
    class Runner implements Runnable {
        private int no;
        private CountDownLatch begin;
        private CountDownLatch end;
    
        public Runner(int no, CountDownLatch begin, CountDownLatch end) {
            this.no = no;
            this.begin = begin;
            this.end = end;
            System.out.println("No." + no + "     。");
        }
    
        @Override
        public void run() {
            try {
                begin.await();//       
                System.out.println("No." + no + "     。。。");
                TimeUnit.SECONDS.sleep(new Random().nextInt(10));//       。。。
            } catch (InterruptedException e) {
            }
            System.out.println("No." + no + "    。");
            end.countDown();
        }
    }
    

    『8195』는 일련의 집행 체인 을 정의 하기 시 작 했 고 첫 번 째 는 선 결 조건 이 없 으 며 직접 집행 했다.두 번 째 는 첫 번 째 를 선 결 조건 으로 하고 이런 식 으로 유추 했다.저 는 게으름뱅이 입 니 다.군말 을 많이 하지 않 습 니 다.제 친구 의 글 에서 잘 썼 습 니 다.Count Downlatch 동기 화 보조 류 를 이용 하여 스 레 드 동기 화 를 합 니 다.
    카운터
    *8195°하나의 카운터 의 상황 은 자신 이 상황 이 비교적 단일 하 다 고 느끼 는데 바로 메 인 스 레 드 가 서브 스 레 드 가 끝나 기 를 기다 리 고 계속 실행 하 는 것 이다.이곳 의 메 인 스 레 드,하위 스 레 드 는 상대 적 으로 메 인 스 레 드 자체 가 다른 스 레 드 의 하위 스 레 드 일 수 있 습 니 다.
    예제 코드:
    public class CountDownLatchTest6 {
        public static void main(String[] args) throws InterruptedException {
            CountDownLatch doneSignal = new CountDownLatch(3);
            ExecutorService e = Executors.newCachedThreadPool();
    
            for (int i = 0; i < 3; ++i) {
                e.execute(new Worker(doneSignal, i));
            }
            doSomethingElse();
            doneSignal.await();//        
            doSomethingElse();
            e.shutdown();
        }
    }
    
    class Worker implements Runnable {
        private final CountDownLatch doneSignal;
        private final int id;
    
        Worker(CountDownLatch doneSignal, int id) {
            this.doneSignal = doneSignal;
            this.id = id;
        }
    
        @Override
        public void run() {
            doWork();
            doneSignal.countDown();
        }
    
        void doWork() {...}
    }
    

      예시 코드 중의 doSomethingElse 방법 은 일부 업무 논리 코드 로 구체 적 인 기능 에 따라 변화 할 수 있다.
      이런 방식 에 대해 지난 편 에서 사장 과 노동자 에 관 한 예 중의 두 번 째 해결 방법 인 다 중 스 레 드 001-메 인 스 레 드 는 하위 스 레 드 가 끝 날 때 까지 기다 릴 수 있 고 여기 서도 군말 하지 않 습 니 다.

    좋은 웹페이지 즐겨찾기