Java에서 CyclicBarrier 사이클 장벽을 적용하는 방법
1. 소개
CyclicBarrier는 말 그대로 루프 장벽(순환 장벽)을 의미합니다. 스레드 그룹이 특정 상태(장벽 지점)를 기다리게 한 다음 동시에 실행하도록 할 수 있습니다. 모든 대기 스레드가 해제된 후에 CyclicBarrier를 재사용할 수 있기 때문에 이를 루프백이라고 합니다.
CyclicBarrier의 기능은 스레드 그룹이 공통 지점에 도달하면 이전에 대기 중인 모든 스레드가 계속 실행되며 CyclicBarrier 기능을 재사용할 수 있습니다.
2. CyclicBarrier 사용
구성 방법:
// parties表示屏障拦截的线程数量,每个线程调用 await 方法告诉 CyclicBarrier 我已经到达了屏障,然后当前线程被阻塞。 public CyclicBarrier(int parties) // 用于在线程到达屏障时,优先执行 barrierAction,方便处理更复杂的业务场景(该线程的执行时机是在到达屏障之后再执行)
중요 방법:
//屏障 指定数量的线程全部调用await()方法时,这些线程不再阻塞 // BrokenBarrierException 表示栅栏已经被破坏,破坏的原因可能是其中一个线程 await() 时被中断或者超时 public int await() throws InterruptedException, BrokenBarrierException public int await(long timeout, TimeUnit unit) throws InterruptedException, BrokenBarrierException, TimeoutException //循环 通过reset()方法可以进行重置
CyclicBarrier 적용 시나리오
CyclicBarrier 사용 가능 데이터의 멀티스레드 계산을 위해 최종적으로 병합 계산 결과.
카운터를 재설정하고 장벽을 재사용할 수 있는 CyclicBarrier의 기능을 활용하여 "기차가 사람으로 가득 찼습니다"와 유사한 시나리오를 지원할 수 있습니다.
병합 계산 시나리오 시뮬레이션
CyclicBarrier를 사용하여 계산 여러 스레드의 데이터, 마지막으로 계산 결과 병합 시나리오입니다.
public class CyclicBarrierTest2 { //保存每个学生的平均成绩 private Conc urrentHashMap<String, Integer> map=new ConcurrentHashMap<String,Integer>(); private ExecutorService threadPool= Executors.newFixedThreadPool(3); private CyclicBarrier cb=new CyclicBarrier(3,()->{ int result=0; Set<String> set = map.keySet(); for(String s:set){ result+=map.get(s); } System.out.println("三人平均成绩为:"+(result/3)+"分"); }); public void count(){ for(int i=0;i<3;i++){ threadPool.execute(new Runnable(){ @Override public void run() { //获取学生平均成绩 int score=(int)(Math.random()*40+60); map.put(Thread.currentThread().getName(), score); System.out.println(Thread.currentThread().getName() +"同学的平均成绩为:"+score); try { //执行完运行await(),等待所有学生平均成绩都计算完毕 cb.await(); } catch (InterruptedException | BrokenBarrierException e) { e.printStackTrace(); } } }); } } public static void main(String[] args) { CyclicBarrierTest2 cb=new CyclicBarrierTest2(); cb.count(); } }
"기차는 사람으로 가득하다" 장면을 시뮬레이션합니다
카운터를 재설정하고 장벽을 재사용할 수 있는 CyclicBarrier의 기능을 사용하여 "기차는 사람으로 가득하다" 장면을 지원할 수 있습니다
public class CyclicBarrierTest3 { public static void main(String[] args) { AtomicInteger counter = new AtomicInteger(); ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor( 5, 5, 1000, TimeUnit.SECONDS, new ArrayBlockingQueue<>(100), (r) -> new Thread(r, counter.addAndGet(1) + " 号 "), new ThreadPoolExecutor.AbortPolicy()); CyclicBarrier cyclicBarrier = new CyclicBarrier(5, () -> System.out.println("裁判:比赛开始~~")); for (int i = 0; i < 10; i++) { threadPoolExecutor.submit(new Runner(cyclicBarrier)); } } static class Runner extends Thread{ private CyclicBarrier cyclicBarrier; public Runner (CyclicBarrier cyclicBarrier) { this.cyclicBarrier = cyclicBarrier; } @Override public void run() { try { int sleepMills = ThreadLocalRandom.current().nextInt(1000); Thread.sleep(sleepMills); System.out.println(Thread.currentThread().getName() + " 选手已就位, 准备共用时: " + sleepMills + "ms" + cyclicBarrier.getNumberWaiting()); cyclicBarrier.await(); } catch (InterruptedException e) { e.printStackTrace(); }catch(BrokenBarrierException e){ e.printStackTrace(); } } } }
출력 결과:
3 1번 선수가 위치에 있고, 공유할 준비가 되었습니다: 78ms 0
1명의 선수가 위치에 있고, 공유할 준비가 되었습니다: 395ms 1
5명의 선수가 위치에 있고, 공유할 준비가 되었습니다: 733ms 2
2명의 선수가 위치에 있고, 공유할 준비가 되었습니다: 776ms3
4번 선수가 위치에 있고, 공유할 준비가 되었습니다: 807ms4
심판: 게임이 시작되었습니다~~
4번 선수가 위치에 있고, 공유할 준비가 되었습니다: 131ms0
3번 선수가 위치에 있고, 공유할 준비가 되어 있음: 256ms1
2번 선수가 이미 자리에 있고, 공유할 준비가 되어 있음: 291ms2
1번 선수가 자리에 있고, 공유할 준비가 되어 있음: 588ms3
5번 선수가 자리에 있음 , 공유 준비 완료: 763ms4
심판자: 게임이 시작되었습니다~~
3. CyclicBarrier 소스 코드 분석
CyclicBarrier 프로세스
주요 프로세스는 다음과 같습니다.
잠금을 설정하고 카운트되면 차단에 들어갑니다! = 0;
-
차단에 들어가기 전에 먼저 조건 대기열에 들어간 다음 잠금을 해제하고 마지막으로 차단해야 합니다.
count != 0이면 깨우기가 수행되고 모든 노드가 조건 대기열은 차단 대기열로 변환됩니다.
잠금 획득에 실패하면 잠금이 성공적으로 획득되면 잠금을 획득합니다. 잠금이 해제되고 동기화 큐의 스레드가 깨어납니다.
- 다음은 간단한 흐름도입니다.
다음은 일부 코드 호출의 구체적인 프로세스입니다.
몇 가지 일반적인 질문이 있으신가요?
1. 스레드 그룹은 장벽을 트리거하기 전에 서로를 기다립니다. 마지막 스레드가 장벽에 도달한 후 깨우기 프로세스는 어떻게 구현됩니까? 업 상태 큐.
2. 열 삭제 주기는 어떻게 구현되나요? 실제로 뮤텍스 ReentrantLock의 조건 대기열과 차단 대기열이 변환됩니다.
java.util.concurrent.locks.Condition#signalAll
- 3. 조건 대기열에서 동기화 대기열로의 변환 논리? 변환 프로세스 중에 조건 대기열의 모든 차단된 스레드가 먼저 깨어나고 획득에 실패하면 잠금이 획득됩니다. 동기화 대기열.
- CyclicBarrier와 CountDownLatch의 차이점
- CountDownLatch는 메인 스레드를 차단하고 CyclicBarrier는 메인 스레드를 차단하지 않고 하위 스레드만 차단합니다.
- CountDownLatch와 CyclicBarrier는 둘 다 스레드 간 대기를 구현할 수 있지만 초점이 다릅니다. CountDownLatch는 일반적으로 하나 이상의 스레드가 다른 스레드가 작업을 실행하기 전에 완료할 때까지 기다리는 데 사용됩니다. CyclicBarrier는 일반적으로 스레드 그룹이 서로 특정 상태에 도달할 때까지 기다린 다음 스레드 그룹이 동시에 실행되는 데 사용됩니다.
- CyclicBarrier는 멀티스레드 계산 결과를 병합하는 BarrierAction도 제공할 수 있습니다.
CyclicBarrier는 ReentrantLock의 "독점 잠금" 및 Conditon을 통해 스레드 그룹의 차단 및 깨우기를 구현하는 반면, CountDownLatch는 AQS의 "공유 잠금"
위 내용은 Java에서 CyclicBarrier 사이클 장벽을 적용하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











Java의 Weka 가이드. 여기에서는 소개, weka java 사용 방법, 플랫폼 유형 및 장점을 예제와 함께 설명합니다.

Java의 Smith Number 가이드. 여기서는 정의, Java에서 스미스 번호를 확인하는 방법에 대해 논의합니다. 코드 구현의 예.

이 기사에서는 가장 많이 묻는 Java Spring 면접 질문과 자세한 답변을 보관했습니다. 그래야 면접에 합격할 수 있습니다.

Java 8은 스트림 API를 소개하여 데이터 컬렉션을 처리하는 강력하고 표현적인 방법을 제공합니다. 그러나 스트림을 사용할 때 일반적인 질문은 다음과 같은 것입니다. 기존 루프는 조기 중단 또는 반환을 허용하지만 스트림의 Foreach 메소드는이 방법을 직접 지원하지 않습니다. 이 기사는 이유를 설명하고 스트림 처리 시스템에서 조기 종료를 구현하기위한 대체 방법을 탐색합니다. 추가 읽기 : Java Stream API 개선 스트림 foreach를 이해하십시오 Foreach 메소드는 스트림의 각 요소에서 하나의 작업을 수행하는 터미널 작동입니다. 디자인 의도입니다

Java의 TimeStamp to Date 안내. 여기서는 소개와 예제와 함께 Java에서 타임스탬프를 날짜로 변환하는 방법에 대해서도 설명합니다.

캡슐은 3 차원 기하학적 그림이며, 양쪽 끝에 실린더와 반구로 구성됩니다. 캡슐의 부피는 실린더의 부피와 양쪽 끝에 반구의 부피를 첨가하여 계산할 수 있습니다. 이 튜토리얼은 다른 방법을 사용하여 Java에서 주어진 캡슐의 부피를 계산하는 방법에 대해 논의합니다. 캡슐 볼륨 공식 캡슐 볼륨에 대한 공식은 다음과 같습니다. 캡슐 부피 = 원통형 볼륨 2 반구 볼륨 안에, R : 반구의 반경. H : 실린더의 높이 (반구 제외). 예 1 입력하다 반경 = 5 단위 높이 = 10 단위 산출 볼륨 = 1570.8 입방 단위 설명하다 공식을 사용하여 볼륨 계산 : 부피 = π × r2 × h (4

Spring Boot는 강력하고 확장 가능하며 생산 가능한 Java 응용 프로그램의 생성을 단순화하여 Java 개발에 혁명을 일으킨다. Spring Ecosystem에 내재 된 "구성에 대한 협약"접근 방식은 수동 설정, Allo를 최소화합니다.
