Java 中实现主线程等待子线程

Thread 类的 join() 方法可以让主线程等待某个线程执行完毕

public class ThreadJoinExample {public static void main(String[] args) throws InterruptedException {Thread thread1 = new Thread(() -> {System.out.println("Thread 1 is running");try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("Thread 1 finished");});Thread thread2 = new Thread(() -> {System.out.println("Thread 2 is running");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("Thread 2 finished");});thread1.start();thread2.start();// 主线程等待子线程thread1.join();thread2.join();System.out.println("All threads finished. Main thread continues.");}
}

CountDownLatch是一个线程同步工具类,可以让主线程等待多个线程完成任务

public class CountDownLatchExample {public static void main(String[] args) throws InterruptedException {int threadCount = 2;CountDownLatch latch = new CountDownLatch(threadCount);Runnable task = () -> {System.out.println(Thread.currentThread().getName() + " is running");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + " finished");latch.countDown(); // 计数器减1};Thread thread1 = new Thread(task, "Thread 1");Thread thread2 = new Thread(task, "Thread 2");thread1.start();thread2.start();latch.await(); // 主线程等待计数器归零System.out.println("All threads finished. Main thread continues.");}
}

使用ExecutorService可以方便地管理线程池,并通过invokeAll()等待所有线程完成

public class ExecutorServiceExample {public static void main(String[] args) throws InterruptedException {ExecutorService executor = Executors.newFixedThreadPool(2);List<Callable<Void>> tasks = new ArrayList<>();tasks.add(() -> {System.out.println("Task 1 is running");Thread.sleep(1000);System.out.println("Task 1 finished");return null;});tasks.add(() -> {System.out.println("Task 2 is running");Thread.sleep(2000);System.out.println("Task 2 finished");return null;});executor.invokeAll(tasks); // 等待所有任务完成System.out.println("All tasks finished. Main thread continues.");executor.shutdown();}
}

如果任务可以分而治之,可以使用ForkJoinPool框架

public class ForkJoinPoolExample {static class SumTask extends RecursiveTask<Long> {private static final int THRESHOLD = 10; // 阈值,决定任务拆分的粒度private final int[] array;private final int start;private final int end;public SumTask(int[] array, int start, int end) {this.array = array;this.start = start;this.end = end;}@Overrideprotected Long compute() {if (end - start <= THRESHOLD) {// 任务足够小,直接计算long sum = 0;for (int i = start; i < end; i++) {sum += array[i];}return sum;} else {// 任务太大,分成两个子任务int mid = (start + end) / 2;SumTask leftTask = new SumTask(array, start, mid);SumTask rightTask = new SumTask(array, mid, end);// 递归执行子任务leftTask.fork(); // 异步执行long rightResult = rightTask.compute(); // 当前线程直接执行右任务long leftResult = leftTask.join(); // 等待左任务结果// 合并结果return leftResult + rightResult;}}}public static void main(String[] args) {// 创建一个大数组int[] array = new int[100];for (int i = 0; i < array.length; i++) {array[i] = i + 1;}// 创建 ForkJoinPoolForkJoinPool forkJoinPool = new ForkJoinPool(4);// 提交主任务SumTask task = new SumTask(array, 0, array.length);long result = forkJoinPool.invoke(task); // 阻塞等待结果System.out.println("Sum of array elements: " + result);// 关闭 ForkJoinPoolforkJoinPool.shutdown();}
}

ExecutorService的shutdown() + awaitTermination(),这种方法通过线程池的关闭操作配合awaitTermination()来等待线程池中的所有任务完成

public class ThreadPoolAwaitExample {public static void main(String[] args) throws InterruptedException {ExecutorService executor = Executors.newFixedThreadPool(3);for (int i = 1; i <= 5; i++) {int taskId = i;executor.submit(() -> {System.out.println("Task " + taskId + " is running");try {Thread.sleep(1000); // 模拟任务耗时} catch (InterruptedException e) {e.printStackTrace();}System.out.println("Task " + taskId + " completed");});}executor.shutdown(); // 禁止提交新任务if (executor.awaitTermination(5, TimeUnit.SECONDS)) { // 等待所有任务完成,超时时间可调整System.out.println("All tasks completed. Main thread continues.");} else {System.out.println("Timeout reached before tasks completed.");}}
}

使用 CompletionService,CompletionService可以结合线程池使用,用于提交和获取任务的执行结果。通过轮询结果,确保所有任务完成

public class CompletionServiceExample {public static void main(String[] args) throws InterruptedException, ExecutionException {ExecutorService executor = Executors.newFixedThreadPool(3);CompletionService<String> completionService = new ExecutorCompletionService<>(executor);for (int i = 1; i <= 5; i++) {int taskId = i;completionService.submit(() -> {Thread.sleep(1000);return "Task " + taskId + " result";});}for (int i = 1; i <= 5; i++) {Future<String> future = completionService.take(); // 阻塞直到有结果可获取System.out.println(future.get());}executor.shutdown();System.out.println("All tasks completed. Main thread continues.");}
}

通过 Future 的 get(),ExecutorService 的 submit() 方法返回一个 Future 对象,可以通过 Future.get() 阻塞等待任务完成。

public class FutureGetExample {public static void main(String[] args) throws InterruptedException, ExecutionException {ExecutorService executor = Executors.newFixedThreadPool(3);List<Future<String>> futures = new ArrayList<>();for (int i = 1; i <= 5; i++) {int taskId = i;futures.add(executor.submit(() -> {Thread.sleep(1000);return "Task " + taskId + " result";}));}for (Future<String> future : futures) {System.out.println(future.get()); // 阻塞等待任务完成}executor.shutdown();System.out.println("All tasks completed. Main thread continues.");}
}

invokeAll() 方法,ExecutorService 提供了 invokeAll() 方法,可以一次性提交一组任务,并阻塞直到所有任务完成。

public class InvokeAllExample {public static void main(String[] args) throws InterruptedException, ExecutionException {ExecutorService executor = Executors.newFixedThreadPool(3);List<Callable<String>> tasks = new ArrayList<>();for (int i = 1; i <= 5; i++) {int taskId = i;tasks.add(() -> {Thread.sleep(1000);return "Task " + taskId + " result";});}List<Future<String>> futures = executor.invokeAll(tasks); // 阻塞等待所有任务完成for (Future<String> future : futures) {System.out.println(future.get());}executor.shutdown();System.out.println("All tasks completed. Main thread continues.");}
}

使用 CountDownLatch,通过线程池配合 CountDownLatch 实现主线程等待所有任务完成。

public class CountDownLatchExample {public static void main(String[] args) throws InterruptedException {int taskCount = 5;CountDownLatch latch = new CountDownLatch(taskCount);ExecutorService executor = Executors.newFixedThreadPool(3);for (int i = 1; i <= taskCount; i++) {int taskId = i;executor.submit(() -> {try {System.out.println("Task " + taskId + " is running");Thread.sleep(1000); // 模拟任务耗时} catch (InterruptedException e) {e.printStackTrace();} finally {latch.countDown(); // 每完成一个任务,计数器减1}System.out.println("Task " + taskId + " completed");});}latch.await(); // 主线程等待计数器归零executor.shutdown();System.out.println("All tasks completed. Main thread continues.");}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/35588.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

C# WPF抽奖程序

C# WPF抽奖程序 using Microsoft.Win32; using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows; using System.…

Master EDI 项目需求分析

Master Electronics 通过其全球分销网络&#xff0c;支持多种采购需求&#xff0c;确保能够为客户提供可靠的元件供应链解决方案&#xff0c;同时为快速高效的与全球伙伴建立合作&#xff0c;Master 选择通过EDI来实现与交易伙伴间的数据传输。 EDI为交易伙伴之间建立了一个安…

基于单片机的输液速度监控系统设计

本设计是以STM32F103C8T6单片机为控制核心&#xff0c;用户可通过按键模块来设置液体高度与点滴速度的阈值&#xff0c;采用液位传感器实时监测瓶内液体位置&#xff0c;若液位低于所设阈值&#xff0c;蜂鸣器进行声音报警提醒患者或医生。采用步进电机通过控制输液管直径大小从…

河工oj新生周赛第八周2024

A.小七的作业 小柒的作业 - 问题 - 软件学院OJ 代码 #include<bits/stdc.h> using namespace std;int main() {string s;cin >> s;int l, r;cin >> l >> r;string str s.substr(l,r-l1);cout << str;return 0; } B.小七的签到题 小柒的签到…

FPGA工作原理、架构及底层资源

FPGA工作原理、架构及底层资源 文章目录 FPGA工作原理、架构及底层资源前言一、FPGA工作原理二、FPGA架构及底层资源 1.FPGA架构2.FPGA底层资源 2.1可编程输入/输出单元简称&#xff08;IOB&#xff09;2.2可配置逻辑块2.3丰富的布线资源2.4数字时钟管理模块(DCM)2.5嵌入式块 …

低功耗蓝牙模块在高尔夫测距仪上的应用

在绿意盎然的高尔夫球场上&#xff0c;每一次挥杆都承载着球员对精准与完美的追求。随着科技的飞速发展&#xff0c;高尔夫运动也迎来了智能化的革新。一款集成了先进蓝牙模组的高尔夫测距仪&#xff0c;它不仅重新定义了高尔夫运动的测距精度&#xff0c;更以无线互联的便捷性…

如何在 cPanel 中创建子域名:分步指南

cPanel 是一个用于管理网站的工具&#xff0c;操作界面简单直观&#xff0c;常用于管理网站的各种功能&#xff0c;包括创建子域名。很多知名的网络服务提供商&#xff0c;如 Hostease&#xff0c;都提供了 cPanel 管理工具。 本文将详细介绍如何在 cPanel 中创建子域名&#x…

减少30%人工处理时间,AI OCR与表格识别助力医疗化验单快速处理

在医疗行业&#xff0c;化验单作为重要的诊断依据和数据来源&#xff0c;涉及大量的文字和表格信息&#xff0c;传统的手工输入和数据处理方式不仅繁琐&#xff0c;而且容易出错&#xff0c;给医院的运营效率和数据准确性带来较大挑战。随着人工智能技术的快速发展&#xff0c;…

Linux安装BellSoft JDK 17 LTS

原来使用的OpenJdk&#xff0c;看到SpringBoot官网推荐&#xff08;如下图&#xff09;贝尔实验室的JDK&#xff0c;打算换一下 官方下载链接 JKD下载 可以看到Win、Mac、Linux都提供了&#xff0c;并且还有x86架构和arm架构的 在Linux中我们可以使用 uname -a 查看当前操作系…

C++(九)

前言&#xff1a; 本文主要讲述运算符的优先顺序。 一&#xff0c;运算符的优先级。 请看以下表达式&#xff1a; a32*5 运算结果为&#xff1a;13. 可以看到&#xff0c;在此代码中&#xff0c;先运行了2*5的结果&#xff0c;在此基础上在进行3操作&#xff0c;因此结果…

学生公寓智能限电系统的功能和作用

学生公寓智能限电系统‌是一种用于管理和限制学生公寓用电的设备和技术&#xff0c;旨在确保用电安全、防止火灾事故&#xff0c;并促进节能减排。以下是关于学生公寓智能限电系统的详细介绍&#xff1a; 1、功能和作用 智能限电系统通过以下功能来管理和限制用电&#xff1a…

嵌入式入门Day25

数据结构Day 6,IO Day1 查找算法顺序查找折半查找&#xff08;二分查找&#xff09;哈希查找 IO概念标准IO创建递归索引&#xff08;用于查询结构体定义&#xff09; 文件IO标准IO缓冲区指针相关函数 查找算法 顺序查找 关键字&#xff1a;分为主关键字和次关键字主关键字&am…

内网代理转发工具

概念区分 端口转发 端口转发就是将一个端口&#xff0c;这个端口可以本机的端口也可以是本机可以访问到的任意主机的端口&#xff0c;转发到任意一台可以访问到的IP上&#xff0c;通常这个IP是公网IP。 适用端口转发的网络环境有以下几种&#xff1a; 服务器处于内网&#x…

MNIST_FC

前言 提醒&#xff1a; 文章内容为方便作者自己后日复习与查阅而进行的书写与发布&#xff0c;其中引用内容都会使用链接表明出处&#xff08;如有侵权问题&#xff0c;请及时联系&#xff09;。 其中内容多为一次书写&#xff0c;缺少检查与订正&#xff0c;如有问题或其他拓展…

掌握时间,从`datetime`开始

文章目录 掌握时间&#xff0c;从datetime开始第一部分&#xff1a;背景介绍第二部分&#xff1a;datetime库是什么&#xff1f;第三部分&#xff1a;如何安装这个库&#xff1f;第四部分&#xff1a;简单库函数使用方法1. 获取当前日期和时间2. 创建特定的日期3. 计算两个日期…

算法之括号匹配中最长有效字符串

目录 1. 题目2. 解释3. 思路4. 代码5. 总结 1. 题目 任何一个左括号都能找到和其正确配对的右括号任何一个右括号都能找到和其正确配对的左括号 求最长的有效的括号长度 2. 解释 例如&#xff0c;这里的括号 ((((()()()()()()()))()最长有效是&#xff1a;((()()()()()()(…

统信桌面专业版部署postgresql-14.2+postgis-3.2方法介绍

文章来源&#xff1a;统信桌面专业版部署postgresql-14.2postgis-3.2方法介绍 | 统信软件-知识分享平台 应用场景 CPU架构&#xff1a;X86&#xff08;海光C86-3G 3350&#xff09; OS版本信息&#xff1a;1070桌面专业版 软件信息&#xff1a;postgresql-14.2postgis-3.2 …

【书生大模型实战营】Python 基础知识-L0G2000

前言&#xff1a;本文是书生大模型实战营系列的第2篇文章&#xff0c;是入门岛的第二个任务&#xff0c;主题为&#xff1a;Python基础知识。 官方教程参考链接&#xff1a;Tutorial/docs/L0/Python at camp4 InternLM/Tutorial 1.任务概览 本关为Python基础关卡&#xff0…

智能安全新时代:大语言模型与智能体在网络安全中的革命性应用

一、引言 随着信息技术的飞速发展&#xff0c;网络安全问题日益严重&#xff0c;成为各行各业面临的重大挑战。传统的安全防护措施已难以应对日益复杂的网络威胁&#xff0c;人工智能&#xff08;AI&#xff09;技术的引入为网络安全带来了新的希望。特别是大语言模型&#xff…

数仓技术hive与oracle对比(三)

更新处理 oracle使用dblink透明网关连接其他数据库&#xff0c;mysql、sqlserver、oracle&#xff0c;然后用sql、plsql更新数据&#xff1b;或者使用etl工具实现更新。 hive使用sqoop连接mysql、sqlserver、oracle实现数据更新。 oracle oracle数据加载命令 批量sql脚本上…