[창해 습득]자바 병발 의 Count Downlatch,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 과정 과 유사 합 니 다.상대 적 으로 그 에 게 도 두 가지 주요 한 방법 이 있다.
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
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.