让我们详细讲解“Java实现限定时间CountDownLatch并行场景”的完整攻略。
CountDownLatch概述
CountDownLatch是Java中一个非常实用的工具,它可以用于协调多个线程之间的同步操作。它可以让等待某个特定条件发生的线程一直等待下去,直到该条件被满足后,所有等待的线程才会同时被唤醒并继续执行。
CountDownLatch的核心思想就是一个计数器,该计数器被初始化为一个正整数,并且在某些操作发生之后被递减。一组等待中的线程可以被阻塞,直到计数器为零。如果你只是需要一个简单的同步工具,并不像Semaphore这样复杂和强大,那么CountDownLatch是个不错的选择。
CountDownLatch的使用
CountDownLatch的使用比较简单,主要包括以下步骤:
- 创建一个CountDownLatch对象,并指定计数器的初始值(即需要等待的操作数)。
- 在工作线程中执行需要等待的操作。
- 在等待线程中使用await()方法等待操作完成。
- 在工作线程中完成每个操作时,使用countDown()方法递减计数器的值。
Java实现限定时间CountDownLatch并行场景攻略及示例代码
Java实现限定时间CountDownLatch并行场景攻略的步骤如下:
- 创建一个 CountDownLatch 对象,计数器的初始值设为要等待的操作数 N,即需要等待 N 个线程的操作完成。
- 在每个工作线程中执行相应的任务,然后使用 countDown() 方法递减计数器的值。如果递减后的值为0,则所有操作已完成。
- 在等待线程中,调用 await(long timeout, TimeUnit unit) 方法等待操作完成或超时。超时时间可以由参数指定。
下面是示例代码,其中有两个工作线程并行执行,主线程等待它们完成或超时:
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
public class CountDownLatchDemo {
private static final int WORKER_NUM = 2;
private static final int WAIT_TIME = 5000;
public static void main(String[] args) throws InterruptedException {
CountDownLatch latch = new CountDownLatch(WORKER_NUM);
// 创建两个工作线程
new Thread(new Worker(latch, "Worker1")).start();
new Thread(new Worker(latch, "Worker2")).start();
// 在主线程中等待操作完成或超时
if (latch.await(WAIT_TIME, TimeUnit.MILLISECONDS)) {
System.out.println("All workers finished the job!");
} else {
System.out.println("Timeout! Some workers are not finished yet.");
}
}
// 工作线程
static class Worker implements Runnable {
private final CountDownLatch latch;
private final String name;
public Worker(CountDownLatch latch, String name) {
this.latch = latch;
this.name = name;
}
@Override
public void run() {
try {
// 执行任务
System.out.println(name + " is starting to work...");
TimeUnit.SECONDS.sleep(3);
System.out.println(name + " finished the job!");
// 递减计数器
latch.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
在上述示例代码中,创建了一个 CountDownLatch 对象 latch,并指定初始值为 2(即需要等待两个工作线程完成操作)。然后创建两个工作线程 Worker1 和 Worker2,在每个工作线程中执行相应任务,最终使用 countDown() 方法递减计数器的值。在主线程中使用 await(long timeout, TimeUnit unit) 方法等待两个工作线程完成操作或超时。如果所有工作线程在指定的时间内完成操作,主线程输出 "All workers finished the job!"。如果有任何一个工作线程还没有完成操作,则主线程输出 "Timeout! Some workers are not finished yet."。
另外,这里再给一个更实际的例子,假如我们需要在10秒内获取多个网站的内容,而每个网站的内容获取可能会需要不同时间,此时我们可以使用CountDownLatch来实现并行获取,然后将结果进行合并。具体操作流程如下:
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
public class CountDownLatchDemo {
private static final int NUM_SITES = 5;
private static final int WAIT_TIME = 10;
private static final Random random = new Random();
public static void main(String[] args) throws InterruptedException {
CountDownLatch latch = new CountDownLatch(NUM_SITES);
List<String> contents = new ArrayList<>();
// 并行获取各个网站的内容
for (int i = 0; i < NUM_SITES; i++) {
new Thread(new SiteContentFetcher(latch, contents)).start();
}
// 等待所有网站的内容获取完成或超时
if (latch.await(WAIT_TIME, TimeUnit.SECONDS)) {
System.out.println("All site contents fetched: " + contents);
} else {
System.out.println("Timeout!");
}
}
// 获取单个网站的内容
static class SiteContentFetcher implements Runnable {
private final CountDownLatch latch;
private final List<String> contents;
public SiteContentFetcher(CountDownLatch latch, List<String> contents) {
this.latch = latch;
this.contents = contents;
}
@Override
public void run() {
try {
// 模拟获取网站内容的时间
long time = random.nextInt(10);
System.out.println(Thread.currentThread().getName() + " fetching site content, time: " + time);
TimeUnit.SECONDS.sleep(time);
// 保存网站内容
contents.add(Thread.currentThread().getName() + ": content");
System.out.println(Thread.currentThread().getName() + " finished fetching site content");
// 递减计数器
latch.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
在上述示例代码中,创建了一个 CountDownLatch 对象 latch,并指定初始值为 NUM_SITES(即需要等待 NUM_SITES 个网站的内容获取完成)。然后创建 NUM_SITES 个获取网站内容的工作线程,在每个工作线程中模拟获取网站内容的时间,实际获取网站内容并将其保存到列表中,最后使用 countDown() 方法递减计数器的值。在主线程中使用 await(long timeout, TimeUnit unit) 方法等待所有工作线程完成操作或超时。如果所有工作线程在指定的时间内完成操作,主线程输出获取到的所有网站内容。如果某个工作线程还没有完成操作,则主线程输出 "Timeout!"。
以上就是关于Java实现限定时间 CountDownLatch 并行场景的完整攻略和两个示例代码。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java实现限定时间CountDownLatch并行场景 - Python技术站