>  기사  >  Java  >  Java 다중 스레드 동기화 도구 클래스 CountDownLatch를 사용하는 방법

Java 다중 스레드 동기화 도구 클래스 CountDownLatch를 사용하는 방법

王林
王林앞으로
2023-05-25 10:22:47998검색

Introduction

CountDownLatch는 멀티 스레드 환경에서 이전 스레드의 실행이 끝날 때까지 여러 스레드가 대기할 수 있도록 하는 멀티 스레드 동기화 도구 클래스입니다. 클래스 이름으로 보아 CountDown은 숫자를 감소시킨다는 의미이므로 카운터로 이해하면 됩니다. CountDownLatch是一个多线程同步工具类,在多线程环境中它允许多个线程处于等待状态,直到前面的线程执行结束。从类名上看CountDown既是数量递减的意思,我们可以把它理解为计数器。

核心方法

  • countDown():计数器递减方法。

  • await():使调用此方法的线程进入等待状态,直到计数器计数为0时主线程才会被唤醒。

  • await(long, TimeUnit):在await()方法的基础上增加了超时策略,若等待超时仍未有结果则会直接唤醒主线程运行。

CountDownLatch如何使用

在这里我们用一段简单的代码进行演示:

@Slf4j
public class CountDownLatchDemo {
    public static void main(String[] args) throws InterruptedException {
        CountDownLatch countDownLatch = new CountDownLatch(3);
        new Thread(() -> {
            log.info("hello this is thread one");
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            countDownLatch.countDown();
        }).start();
        new Thread(() -> {
            log.info("hello this is thread two");
            countDownLatch.countDown();
        }).start();
        new Thread(() -> {
            log.info("hello this is thread three");
            countDownLatch.countDown();
        }).start();
        countDownLatch.await();
        log.info("say good bye!");
    }
}

由上面的代码可见,我们创建了一个CountDownLatch计数器为3和三个线程同步运行。在main主线程中调用了countDownLatch.await()方法使主线程进入阻塞。其中三个线程任务执行完毕后都会调用countDownLatch.countDown()方法对计数器进行递减,当三个线程任务都执行完毕后计数器计数值为0时主线程被唤醒。

注:在创建CountDownLatch实例时必须定义计数器值,一般相对较合理的用法是该值的定义需要经过合理的计算使计数值与需要并行的线程数相等,在每个线程执行完成后做计数递减,最终唤醒主线程继续执行。

  • CountDownLatch计数值设置大于线程数,那么最终所有线程都执行完了,而计数为递减到0那么主线程将会一直处于等待状态。

  • CountDownLatch计数值设置小于并发线程数,那么可能在部分线程未执行完毕时,计数就已经递减到0,则主线程会被提前唤醒。

CountDownLatch运行流程

如下图,主线程阻塞与唤醒的核心就是计数器,只有当所有线程执行完成计数逐个递减最终才会唤起await()阻塞中的主线程。

注:await()可以阻塞一个线程,也可以阻塞多个线程,如果是阻塞多个线程,那么在计数为0时将会唤醒所有被阻塞的线程。

Java 다중 스레드 동기화 도구 클래스 CountDownLatch를 사용하는 방법

运用场景

在简单了解完CountDownLatch的作用后,相信各位最终目的还是想了解如何去使用,在哪些场景下使用更加合适,接下来我就拿一个对账业务的场景详细分析一下。

在当前的情况下,许多平台会与银联、微信、支付宝等支付渠道对接交易,因此无法避免进行对账。对账通常都会在每日的凌晨去处理,一方面是凌晨时间点多数平台访问量都会较小,服务器压力也比较轻松,而且此时出账也比较合理,所以在这个时间点做对账也是一个大数据量计算的操作。

上面讲这么多好像都没说到重点,在处理对账之前首先我们肯定是需要通过各个支付渠道获取对账单文件,那么该如何操作呢?

  • 对账文件下载(第一阶段):在这种情况下可以设计三个任务并发去获取对账文件,使用CountDownLatch阻塞主线程,等待三个任务都获取到文件的时候做计数递减,最终唤醒主线将标记本阶段处理完成,并发起进入下一阶段的通知。

  • 对账文件解析(第二阶段):在上个阶段已下载完成的文件文件中,此阶段要做的就是解析文件。由于三个渠道都是不同的厂家那么文件的内容格式肯定都是不一样的,这时候我们又可以使用CountDownLatch

    핵심 메서드🎜
    • 🎜countDown(): 카운터 감소 메서드. 🎜
    • 🎜await(): 이 메서드를 호출하는 스레드를 대기 상태로 전환합니다. 카운터가 0이 될 때까지 기본 스레드는 깨어나지 않습니다. 🎜
    • 🎜await(long, TimeUnit): 대기 후 결과가 없는 경우 await() 메서드를 기반으로 시간 초과 전략이 추가됩니다. 시간 초과의 경우 실행을 위해 메인 스레드를 직접 깨울 것입니다. 🎜
    🎜CountDownLatch 사용 방법🎜🎜여기에서는 간단한 코드를 사용하여 설명합니다.🎜rrreee🎜위 코드에서 볼 수 있듯이 CountDownLatch 카운터는 3이고 세 개의 스레드가 동시에 실행 중입니다. countDownLatch.await() 메서드는 메인 스레드에서 호출되어 메인 스레드를 차단합니다. 세 개의 스레드 작업이 실행된 후 countDownLatch.countDown() 메서드가 호출되어 카운터를 감소시킵니다. 세 개의 스레드 작업이 모두 실행되면 카운터 값이 0에 도달하고 기본 스레드가 활성화됩니다. 🎜
    🎜참고: CountDownLatch 인스턴스를 생성할 때 카운터 값을 정의해야 합니다. 일반적으로 값을 정의하려면 합리적인 계산이 필요하다는 것이 상대적으로 합리적인 사용법입니다. 카운트 값을 병렬화해야 하는 스레드 수와 동일하게 만듭니다. 각 스레드의 실행이 완료된 후 카운트가 감소하고 마지막으로 메인 스레드가 깨어나 실행을 계속합니다. 🎜
    • 🎜CountDownLatch 카운트 값이 스레드 수보다 크게 설정되면 결국 모든 스레드가 실행되고 횟수가 0으로 감소합니다. 그러면 메인 스레드는 항상 대기 상태에 있게 됩니다. 🎜
    • 🎜CountDownLatch 카운트 값이 동시 스레드 수보다 작게 설정된 경우 일부 스레드가 실행을 완료하기 전에 카운트가 0으로 감소했을 수 있으며, 메인 스레드는 일찍 깨어납니다. 🎜
    🎜CountDownLatch 작업 과정🎜🎜아래와 같이 메인 스레드를 차단하고 깨우는 핵심은 모든 스레드가 실행을 완료하고 카운트가 하나씩 감소할 때만 카운터입니다. await()메인 스레드가 차단되었습니다. 🎜
    🎜참고: await()는 하나의 스레드 또는 여러 스레드를 차단할 수 있습니다. 여러 스레드가 차단되면 개수가 0이 되면 깨어납니다. 차단된 모든 스레드. 🎜
    🎜Java 다중 스레드 동기화 도구 클래스 CountDownLatch를 사용하는 방법 🎜🎜시나리오 활용🎜🎜CountDownLatch의 기능을 간략히 이해한 후, 이를 어떻게 사용하는지, 어떤 시나리오에 사용하는 것이 더 적합한지 이해하는 것이 최종 목표라고 생각합니다. 다음 , 화해 사업을 맡겠습니다. 시나리오를 자세히 분석해 보겠습니다. 🎜🎜현재 상황에서는 많은 플랫폼이 UnionPay, WeChat, Alipay 등 결제 채널과 거래를 연결하므로 화해가 불가피합니다. 조정은 일반적으로 매일 이른 아침에 처리됩니다. 한편, 대부분의 플랫폼은 이른 아침 시간에 방문 수가 적고 서버 압력이 상대적으로 완화되어 있으며 이때 계정이 더 합리적이므로 또한 그렇습니다. 이때 조정을 수행하는 데 적합합니다. 대용량 데이터 계산 작업입니다. 🎜🎜위에 언급된 사항 중 어느 것도 언급되지 않은 것 같습니다. 화해를 처리하기 전에 먼저 다양한 결제 채널을 통해 명세서 파일을 받아야 합니다. 그러면 어떻게 운영해야 할까요? 🎜
    • 🎜조정 파일 다운로드(1단계): 이 경우 조정 파일을 동시에 가져오도록 세 가지 작업을 설계할 수 있습니다. CountDownLatch를 사용하여 메인 스레드를 차단하고 세 가지 작업이 파일을 얻을 때까지 기다린 다음 개수를 줄입니다. 마지막으로 메인 스레드를 깨우면 이 처리 단계가 완료되었음을 표시하고 입력하라는 알림이 시작됩니다. 다음 단계. 🎜
    • 🎜조정 파일 구문 분석(2단계): 이전 단계에서 다운로드한 파일에서 이 단계에서 수행해야 할 작업은 파일을 구문 분석하는 것입니다. 세 채널은 제조업체가 다르기 때문에 파일의 콘텐츠 형식이 달라야 합니다. 이때 CountDownLatch를 사용하여 세 개의 스레드를 시작하여 해당 조정 파일을 구문 분석할 수 있습니다. 업무에 필요한 통일된 형식의 데이터로 변환되어 데이터베이스에 저장되며, 세 가지 작업이 모두 데이터베이스에 저장된 후 메인 스레드가 깨어나 완료로 표시되어 다음 단계의 작업 시작을 알립니다. 🎜
    • 화해 및 정산(3단계): 이전 단계의 데이터가 데이터베이스에 입력된 후 이 단계에서 수행해야 할 작업은 일반적으로 주문 번호와 거래 채널에서 거래 금액이 일치하는지 확인하세요. 금액이 일치하면 거래가 성공적으로 처리됩니다. 그렇지 않으면 해당 거래는 비정상적인 거래로 간주되어 데이터베이스에 저장됩니다. 위의 프로세스 분석을 바탕으로 동시성을 제어하고 비교 트랜잭션 주문을 동시에 처리하는 비교적 합리적인 CountDownLatch计数,结合Semaphore 세마포를 설계할 수 있습니다. 마지막으로 모든 트랜잭션 주문이 처리된 후 메인 스레드가 활성화되어 조정을 표시하고 다음을 알립니다. 계정을 진행하는 단계입니다.

    • 계좌 발행(4단계): 일반적으로 플랫폼은 조정이 완료된 후 계좌를 발행합니다. 즉, 금융 담당자가 통계를 작성할 수 있도록 플랫폼의 업무 규칙에 따라 관련 청구서를 발행합니다. .

위 내용은 Java 다중 스레드 동기화 도구 클래스 CountDownLatch를 사용하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 yisu.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제