Java 语言 多线程倒计时门闩 CountDownLatch 等待多任务完成

Java阿木 发布于 26 天前 4 次阅读


Java多线程倒计时门闩(CountDownLatch)实现多任务同步与等待

在Java并发编程中,多线程同步是一个重要的概念。它确保了多个线程在执行任务时能够按照一定的顺序进行,从而避免数据竞争和资源冲突等问题。本文将围绕Java语言中的`CountDownLatch`类,探讨其在多任务同步与等待中的应用。

`CountDownLatch`是Java并发包(java.util.concurrent)中的一个类,用于实现线程间的同步。它允许一个或多个线程等待其他线程完成某个操作。`CountDownLatch`通过一个计数器实现,计数器的初始值由构造函数指定。每当一个线程完成其任务时,它会调用`countDown()`方法,将计数器减1。当计数器值为0时,所有等待的线程将被释放,继续执行。

CountDownLatch的基本使用

以下是一个简单的`CountDownLatch`使用示例:

java

import java.util.concurrent.CountDownLatch;

public class CountDownLatchExample {


public static void main(String[] args) {


int numberOfTasks = 5;


CountDownLatch latch = new CountDownLatch(numberOfTasks);

for (int i = 0; i < numberOfTasks; i++) {


new Thread(new Task(latch)).start();


}

try {


System.out.println("Waiting for all tasks to complete...");


latch.await();


System.out.println("All tasks completed.");


} catch (InterruptedException e) {


e.printStackTrace();


}


}

static class Task implements Runnable {


private CountDownLatch latch;

public Task(CountDownLatch latch) {


this.latch = latch;


}

@Override


public void run() {


try {


// 模拟任务执行时间


Thread.sleep(1000);


} catch (InterruptedException e) {


e.printStackTrace();


} finally {


latch.countDown();


}


}


}


}


在这个例子中,我们创建了5个任务,每个任务在执行完毕后都会调用`countDown()`方法。主线程通过调用`latch.await()`等待所有任务完成。

CountDownLatch的高级应用

1. 分段执行

在处理大量数据时,我们可以使用`CountDownLatch`实现分段执行,以提高效率。

以下是一个分段执行示例:

java

import java.util.concurrent.CountDownLatch;

public class SegmentExecutionExample {


public static void main(String[] args) {


int totalTasks = 100;


int segmentSize = 10;


CountDownLatch latch = new CountDownLatch(totalTasks);

for (int i = 0; i < totalTasks; i++) {


new Thread(new SegmentTask(latch, i)).start();


}

try {


System.out.println("Waiting for all segments to complete...");


latch.await();


System.out.println("All segments completed.");


} catch (InterruptedException e) {


e.printStackTrace();


}


}

static class SegmentTask implements Runnable {


private CountDownLatch latch;


private int taskId;

public SegmentTask(CountDownLatch latch, int taskId) {


this.latch = latch;


this.taskId = taskId;


}

@Override


public void run() {


try {


// 模拟任务执行时间


Thread.sleep(100);


} catch (InterruptedException e) {


e.printStackTrace();


} finally {


latch.countDown();


}


}


}


}


在这个例子中,我们将100个任务分为10个段,每个段包含10个任务。每个任务执行完毕后,都会调用`countDown()`方法。主线程通过调用`latch.await()`等待所有段完成。

2. 线程池与CountDownLatch

在实际应用中,我们经常使用线程池来管理线程。以下是一个使用线程池和`CountDownLatch`的示例:

java

import java.util.concurrent.CountDownLatch;


import java.util.concurrent.ExecutorService;


import java.util.concurrent.Executors;

public class ThreadPoolCountDownLatchExample {


public static void main(String[] args) {


int numberOfTasks = 5;


CountDownLatch latch = new CountDownLatch(numberOfTasks);


ExecutorService executor = Executors.newFixedThreadPool(3);

for (int i = 0; i < numberOfTasks; i++) {


executor.submit(new Task(latch));


}

executor.shutdown();


try {


System.out.println("Waiting for all tasks to complete...");


latch.await();


System.out.println("All tasks completed.");


} catch (InterruptedException e) {


e.printStackTrace();


}


}

static class Task implements Runnable {


private CountDownLatch latch;

public Task(CountDownLatch latch) {


this.latch = latch;


}

@Override


public void run() {


try {


// 模拟任务执行时间


Thread.sleep(1000);


} catch (InterruptedException e) {


e.printStackTrace();


} finally {


latch.countDown();


}


}


}


}


在这个例子中,我们创建了一个固定大小的线程池,并将任务提交给线程池执行。每个任务执行完毕后,都会调用`countDown()`方法。主线程通过调用`latch.await()`等待所有任务完成。

总结

`CountDownLatch`是Java并发编程中一个非常有用的工具,它可以方便地实现多任务同步与等待。相信读者已经对`CountDownLatch`有了更深入的了解。在实际应用中,我们可以根据需求灵活运用`CountDownLatch`,提高程序的并发性能和稳定性。