Java多线程同步:主线程等待所有子线程执行完成的实现

5星 · 超过95%的资源 需积分: 46 74 下载量 13 浏览量 更新于2024-09-17 1 收藏 116KB DOC 举报
"Java编程中实现主线程等待所有子线程执行完毕的示例代码" 在Java多线程编程中,有时我们需要确保主线程在所有子线程完成它们的工作后才继续执行。这通常用于计算整体执行时间或者进行收尾工作。在提供的描述和代码片段中,展示了如何在Java中实现这个需求。以下是对这段代码的详细解释和相关知识点的扩展: 首先,我们看到`tStart`变量用于记录主线程开始时间,`tEnd`则用于记录主线程结束时间,这两个变量将用于计算所有子线程的总耗时。 代码中创建了一个匿名内部类来实现`Runnable`接口,这是Java中创建线程的一种方式。`Runnable`接口定义了`run()`方法,这是子线程执行的主要逻辑。每个子线程在开始和结束时分别打印一条消息,以便于跟踪它们的执行状态。 在`for`循环中,创建了`threadNum`个线程实例并启动它们。每个线程都绑定一个实现了`Runnable`的实例,这些实例在循环中被初始化。`Thread.start()`方法启动了这些线程,它们将异步地执行。 然而,这段代码并没有提供机制来确保主线程会等待所有子线程完成。为了实现这个功能,我们可以使用以下方法: 1. 使用`CountDownLatch`:主线程可以持有一个`CountDownLatch`,初始计数设置为子线程的数量。每个子线程在完成时调用`countDown()`,主线程在开始时调用`await()`,这将阻塞主线程直到计数归零,意味着所有子线程都已完成。 ```java import java.util.concurrent.CountDownLatch; // 在主线程中 CountDownLatch latch = new CountDownLatch(threadNum); for (int i = 0; i < threadNum; i++) { Thread t = new Thread(r); t.start(); // 在每个子线程启动后,减少计数器 latch.countDown(); } // 主线程等待 latch.await(); // 打印结束标记和总耗时 ``` 2. 使用`join()`:主线程可以调用每个子线程的`join()`方法,这会使主线程等待该子线程完成。但这种方式会阻塞主线程,直到每个子线程完成,不推荐在循环中使用,因为它会导致顺序执行而非并发。 ```java for (int i = 0; i < threadNum; i++) { Thread t = new Thread(r); t.start(); // 等待当前线程完成 t.join(); } // 打印结束标记和总耗时 ``` 3. `ExecutorService`与`Future`:使用`ExecutorService`可以更方便地管理和控制线程,同时可以使用`Future.get()`来等待任务完成。`ExecutorService`提供了更高级的并发控制,如线程池和任务取消等。 ```java ExecutorService executor = Executors.newFixedThreadPool(threadNum); List<Future<?>> futures = new ArrayList<>(threadNum); for (int i = 0; i < threadNum; i++) { Future<?> future = executor.submit(r); futures.add(future); } // 等待所有任务完成 for (Future<?> future : futures) { future.get(); } executor.shutdown(); // 打印结束标记和总耗时 ``` 通过上述方法,我们可以确保主线程在所有子线程完成后再继续执行,并且可以准确地获取所有子线程的总耗时。在实际应用中,选择哪种方法取决于具体需求,例如,如果要考虑资源管理,`ExecutorService`可能是更好的选择。