[창해 습득]자바 병발 의 Count Downlatch,Semaphore,Cyclic Barrier

JAVA 와 가방 에는 Countdown Latch,Semaphore,Cyclic Barrier 등 세 가지 스 레 드 를 동기 화 하 는 데 사용 되 는 행위 가 있 습 니 다.
CountDownLatch
Countdown Latch 는 계수기 가 잠 겨 있 습 니 다.주요 기능 은 await()방법 을 통 해 현재 스 레 드 를 막 은 다음 계수기 가 0 으로 줄 어 들 기 를 기다 리 고 이 스 레 드 를 불 러 일 으 켜 계속 실행 하 는 것 입 니 다.이 클래스 에는 주로 두 가지 방법 이 있 습 니 다.하 나 는 계산 기 를 아래로 줄 이 는 방법 입 니 다.countdown()을 실현 하 는 핵심 코드 는 다음 과 같 습 니 다.
public boolean tryReleaseShared(int releases) {  
	// Decrement count; signal when transition to zero  
	for (;;) {   
	int c = getState();     
	if (c == 0)    
		return false;     
	int nextc = c-1;    
	if (compareAndSetState(c, nextc))    
		return nextc == 0;    
	}    
}    

간단 합 니 다.현재 상태 가 0 이면 이 자물쇠 가 끝 났 음 을 설명 하고 false 로 돌아 갑 니 다.끝 이 없 으 면 계수 기 를 1 로 줄 이 고 compare AndSetState 가 성공 하지 못 하면 계속 순환 합 니 다.계수기 가 0 으로 돌아 오 기 를 기다 리 는 방법 은 await()이다.  Countdown Latch 를 통 해 몇 가지 일 을 할 수 있 습 니 다.
1.메 인 라인 제어 와 함께 스 레 드 를 시작 합 니 다.
final CountDownLatch count = new CountDownLatch(1);
for (int i = 0; i < 3; i++) {
    new Thread("Thread" + i) {
        public void run() {
            System.out.println(Thread.currentThread().getName() + " wait");
            try {
                count.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + " start");
        }
    }.start();
}
//    ,     3          await  
try {
    Thread.sleep(3000);
} catch (InterruptedException e) {
    e.printStackTrace();
}
count.countDown();

2.메 인 스 레 드 는 각 하위 스 레 드 가 모두 실 행 될 때 까지 기 다 렸 다가 다음 과 같이 실행 합 니 다.
final CountDownLatch count = new CountDownLatch(3);
for (int i = 0; i < 3; i++) {
    new Thread("Thread" + i) {
        public void run() {
            System.out.println(Thread.currentThread().getName() + " start");
            count.countDown();
        }
    }.start();
}
try {
    count.await();
} catch (InterruptedException e) {
    e.printStackTrace();
}
System.out.println("All end!!!");    

Semaphore
Semaphore 는 Countdown Latch 와 비슷 합 니 다.다른 점 은 Semaphore 의 값 이 가 져 온 후에 방출 될 수 있다 는 점 입 니 다.Countdown Latch 처럼 끝까지 줄 어 들 지 않 습 니 다.그것 도 밸브 와 같은 기능 으로 유량 을 제한 하 는 데 더 많이 쓰 인 다.일부 자원 에 최대 N 개의 스 레 드 가 접근 할 수 있 도록 제한 하면 N 개 이상 의 주 는 스 레 드 가 더 이상 접근 할 수 없 으 며 기 존 스 레 드 가 끝 난 후에 방출 되 고 새로운 스 레 드 가 들 어 올 수 있 습 니 다.자물쇠 의 lock 과 unlock 과정 과 유사 합 니 다.상대 적 으로 그 에 게 도 두 가지 주요 한 방법 이 있다.
  • 권한 을 가 져 오 는 acquire()의 밑바닥 실현 은 CountDownlatch.countdown()과 유사 합 니 다

  • 4.567917.권한 을 방출 하 는 release()에 사용 되 는데 그 밑 에 있 는 실현 과 acquire()는 서로 거 스 르 는 과정 이다
    Semaphore 로 제한 코드 구현 상세 보기:Semaphore 예
    CyclicBarrier
    Cyclic Barrier 는 하나의 관문 으로 모든 스 레 드 를 막 고 모든 스 레 드 가 관문 에 실 행 될 때 다음 작업 을 통일 적 으로 수행 하 는 것 입 니 다.그 중에서 가장 중요 한 방법 은 await()방법 입 니 다.이 는 다음 과 같 습 니 다.
    private int dowait(boolean timed, long nanos)
        throws InterruptedException, BrokenBarrierException,
               TimeoutException {
        //  ,        1        
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            final Generation g = generation;
    
            if (g.broken)
                throw new BrokenBarrierException();
    
            if (Thread.interrupted()) {
                breakBarrier();
                throw new InterruptedException();
            }
           //          ,      1,    0             ,         
           int index = --count;
           if (index == 0) {  // tripped
               boolean ranAction = false;
               try {
                   //            ,   
    	   final Runnable command = barrierCommand;
                   if (command != null)
                       command.run();
                   ranAction = true;
                   nextGeneration();
                   return 0;
               } finally {
                   if (!ranAction)
                       breakBarrier();
               }
           }
    
            // loop until tripped, broken, interrupted, or timed out
            for (;;) {
                try {
                    if (!timed)
                        trip.await();
                    else if (nanos > 0L)
                        nanos = trip.awaitNanos(nanos);
                } catch (InterruptedException ie) {
                    if (g == generation && ! g.broken) {
                        breakBarrier();
    		throw ie;
    	    } else {
    		// We're about to finish waiting even if we had not
    		// been interrupted, so this interrupt is deemed to
    		// "belong" to subsequent execution.
    		Thread.currentThread().interrupt();
    	    }
                }
    
                if (g.broken)
                    throw new BrokenBarrierException();
    
                if (g != generation)
                    return index;
    
                if (timed && nanos <= 0L) {
                    breakBarrier();
                    throw new TimeoutException();
                }
            }
        } finally {
            lock.unlock();
        }
    }    

    즉,모든 스 레 드 가 실 행 된 후에 await()를 호출 한 다음 에 await()에서 스 레 드 는 먼저 계수 기 를 1 로 줄 이 고 카운터 가 0 이면 정 의 된 작업 을 한 다음 에 원래 스 레 드 의 내용 을 계속 실행 합 니 다.  이 유형 은 이전 두 가지 유형의 장점 중 하 나 는 절단면 프로 그래 밍 과 유사 하 다 는 것 이다.우 리 는 같은 스 레 드 의 특정한 절단면 에서 논 리 를 자 르 고 모든 스 레 드 의 실행 속 도 를 동기 화 할 수 있다.예 코드 는 다음 과 같 습 니 다.
    final CyclicBarrier barrier = new CyclicBarrier(4, new Runnable() {
    
        @Override
        public void run() {
            System.out.println("All Threads Here");
    
        }
    });
    for (int i = 0; i < 4; i++) {
        new Thread("Thread" + i) {
            public void run() {
                System.out.println(Thread.currentThread().getName() + " wait");
                try {
                    barrier.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + " crossed");
            }
        }.start();
    }  

    최종 출력 결 과 는:
    Thread0 wait Thread1 wait  Thread2 wait  Thread3 wait  All Threads Here  Thread0 crossed  Thread1 crossed  Thread2 crossed  Thread3 crossed

    좋은 웹페이지 즐겨찾기