多线程学习之路
多线程的创建方式主要有以下几种:
1. 继承 Thread 类
通过继承 Thread 类并重写 run() 方法来创建线程。
class MyThread extends Thread {@Overridepublic void run() {// 线程执行的任务System.out.println("Thread is running");}
}public class Main {public static void main(String[] args) {MyThread thread = new MyThread();thread.start(); // 启动线程}
}
2. 实现 Runnable 接口
通过实现 Runnable 接口并实现 run() 方法,然后将 Runnable 对象传递给 Thread 类的构造函数。
class MyRunnable implements Runnable {@Overridepublic void run() {// 线程执行的任务System.out.println("Thread is running");}
}public class Main {public static void main(String[] args) {MyRunnable myRunnable = new MyRunnable();Thread thread = new Thread(myRunnable);thread.start(); // 启动线程}
}
3. 实现 Callable 接口
通过实现 Callable 接口并实现 call() 方法,Callable 可以返回结果并抛出异常。通常与 ExecutorService 一起使用。
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;class MyCallable implements Callable<String> {@Overridepublic String call() throws Exception {// 线程执行的任务return "Thread is running";}
}public class Main {public static void main(String[] args) {ExecutorService executor = Executors.newSingleThreadExecutor();MyCallable myCallable = new MyCallable();Future<String> future = executor.submit(myCallable);try {String result = future.get(); // 获取线程执行结果System.out.println(result);} catch (InterruptedException | ExecutionException e) {e.printStackTrace();} finally {executor.shutdown();}}
}
4. 使用线程池
通过 ExecutorService 和 Executors 工具类创建线程池,提交任务给线程池执行。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class Main {public static void main(String[] args) {ExecutorService executor = Executors.newFixedThreadPool(5);for (int i = 0; i < 10; i++) {Runnable task = new MyRunnable();executor.execute(task);}executor.shutdown();}
}
5. 使用 CompletableFuture(Java 8+)
CompletableFuture 提供了更高级的异步编程方式,支持链式调用和组合多个异步任务。
import java.util.concurrent.CompletableFuture;public class Main {public static void main(String[] args) {CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {// 异步执行的任务System.out.println("Thread is running");});future.join(); // 等待任务完成}
}
6. 使用 Timer 和 TimerTask
Timer 和 TimerTask 可以用于创建定时任务,TimerTask 实现了 Runnable 接口。
import java.util.Timer;
import java.util.TimerTask;public class Main {public static void main(String[] args) {Timer timer = new Timer();TimerTask task = new TimerTask() {@Overridepublic void run() {// 定时执行的任务System.out.println("Thread is running");}};timer.schedule(task, 0, 1000); // 延迟0毫秒,每隔1000毫秒执行一次}
}
7. 使用 ForkJoinPool(Java 7+)
ForkJoinPool 是用于并行执行任务的线程池,特别适合分治算法和递归任务。
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveAction;class MyRecursiveAction extends RecursiveAction {@Overrideprotected void compute() {// 并行执行的任务System.out.println("Thread is running");}
}public class Main {public static void main(String[] args) {ForkJoinPool pool = new ForkJoinPool();MyRecursiveAction task = new MyRecursiveAction();pool.invoke(task);}
}
8.list.parallelStream()
import java.util.Arrays;
import java.util.List;
public class ParallelStream {public static void main(String[] args) {List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9,10);list.parallelStream().forEach(System.out::println);}}
parallelStream 是基于 Fork/Join 框架 实现的,它允许将任务拆分成多个子任务并行处理,最后将结果合并。以下是 parallelStream 的底层实现原理:
- Fork/Join 框架
parallelStream 的并行处理依赖于 Java 7 引入的 Fork/Join 框架。该框架的核心思想是:
分治(Divide and Conquer):将一个大任务拆分成多个小任务(Fork),并行执行这些小任务,最后将结果合并(Join)。
工作窃取(Work Stealing):每个线程维护一个任务队列,当某个线程完成任务后,可以从其他线程的队列中“窃取”任务来执行,从而提高 CPU 利用率。 - 并行流的执行流程
当调用 parallelStream() 时,Java 会创建一个并行流,其底层执行流程如下:
(1) 任务拆分
数据源(如集合)会被拆分成多个子任务。
拆分的方式取决于数据源的类型:
对于 ArrayList 等可拆分的数据结构,会按照索引范围拆分成多个子任务。
对于 HashSet 等不可直接拆分的数据结构,会先转换为数组再进行拆分。
(2) 并行执行
每个子任务会被提交到 Fork/Join 线程池(ForkJoinPool.commonPool())中执行。
默认情况下,线程池的大小为 CPU 核心数 - 1(可以通过 -Djava.util.concurrent.ForkJoinPool.common.parallelism 参数调整)。
(3) 结果合并
每个子任务执行完成后,结果会被合并(Join)。
合并的方式取决于流的操作类型(如 reduce、collect 等)。 - 并行流的性能优化
数据量:并行流适合处理大规模数据,小数据量时串行流(stream())可能更快,因为并行化会引入额外的开销(如任务拆分、线程调度等)。
数据结构:数据源的结构影响拆分效率。ArrayList 和数组等支持随机访问的数据结构更适合并行流,而 LinkedList 等链表结构则不适合。
操作类型:某些操作(如 filter、map)适合并行化,而某些操作(如 limit、findFirst)可能会限制并行化的效果。
总结
继承 Thread 类:简单直接,但Java不支持多继承,灵活性较差。
实现 Runnable 接口:更灵活,推荐使用。
实现 Callable 接口:可以返回结果和抛出异常,适合需要返回值的场景。
线程池:高效管理线程资源,适合大量异步任务。
CompletableFuture:支持复杂的异步编程。
Timer 和 TimerTask:适合定时任务。
ForkJoinPool:适合并行计算和分治任务。
根据具体需求选择合适的方式。
相关文章:
多线程学习之路
多线程的创建方式主要有以下几种: 1. 继承 Thread 类 通过继承 Thread 类并重写 run() 方法来创建线程。 class MyThread extends Thread {Overridepublic void run() {// 线程执行的任务System.out.println("Thread is running");} }public class Mai…...
英码科技携昇腾DeepSeek大模型一体机亮相第三届北京人工智能产业创新发展大会
2025年2月28日,第三届北京人工智能产业创新发展大会在国家会议中心隆重开幕。本届大会以"好用、易用、愿用——以突破性创新加速AI赋能千行百业”为主题,重点展示人工智能技术创新成果与产业化应用实践。作为昇腾生态的APN伙伴,英码科技…...
【AI】如何理解与应对AI中的敏感话题:详细分析与实用指南
引言 随着人工智能(AI)技术的不断发展,我们在与AI交互时,可能会遇到敏感话题的讨论限制。在许多情况下,AI系统为了避免触及社会、政治或文化敏感点,会对用户输入进行一定的筛选和过滤。那么,这…...
(十 三)趣学设计模式 之 模版方法模式!
目录 一、 啥是模板方法模式?二、 为什么要用模板方法模式?三、 模板方法模式的实现方式四、 模板方法模式的优缺点五、 模板方法模式的应用场景六、 总结 🌟我的其他文章也讲解的比较有趣😁,如果喜欢博主的讲解方式&a…...
20250225-代码笔记03-class CVRPModel AND other class
文章目录 前言一、class CVRPModel(nn.Module):__init__(self, **model_params)函数功能函数代码 二、class CVRPModel(nn.Module):pre_forward(self, reset_state)函数功能函数代码 三、class CVRPModel(nn.Module):forward(self, state)函数功能函数代码 四、def _get_encodi…...
【postman】postman找回接口数据
项目提测,一打开postman天塌了,所有接口都不见了。。。。conllection目录也看不见了,也导入不了同事给我发的json文件。 然后重新找同事要了一个安装包,覆盖安装了之后,在下面的目录里面找到了备份文件【C:\Users\yan…...
Milvus向量数据库部署
一、什么是Milvus Milvus 是一款开源的向量数据库,旨在帮助开发者轻松管理和检索大规模向量数据。它通过高效的索引技术,支持快速的相似度搜索,使得从海量数据中查找最接近的匹配变得简单而快捷。无论是构建推荐系统、进行图像识别还是分析自…...
显式 GC 的使用:留与去,如何选择?
目录 一、什么是显式 GC? (一) 垃圾回收的基本原理 (二)显式 GC 方法和行为 1. System.gc() 方法 2. 显式 GC 的行为 (三)显式 GC 的使用场景与风险 1. JVM 如何处理显式 GC 2. 显式 GC…...
探秘基带算法:从原理到5G时代的通信变革【二】Viterbi解码
文章目录 二、关键算法原理剖析2.1 Viterbi 解码2.1.1 卷积码与网格图基础**卷积码****网格图****生成多项式****理想情况下解码过程** 2.1.2 Viterbi 算法核心思想2.1.3 路径度量与状态转移机制2.1.4 算法流程与关键步骤详解2.1.5 译码算法举例与复杂度分析2.1.6 算法代码示例…...
从零实现高并发内存池
目录 一、项目介绍 二、什么是内存池? 1.池化技术 2.内存池 3.内存池解决的问题 三、malloc本身就是内存池 四、定长内存池 五、高并发内存池整体框架 六、thread cache 七、central cache 八、page cache 一、项目介绍 当前项目是实现一个高并发的内存池…...
3-7 WPS JS宏 工作表移动复制实例-2(多工作簿的多工作表合并)学习笔记
************************************************************************************************************** 点击进入 -我要自学网-国内领先的专业视频教程学习网站 *******************************************************************************************…...
【计算机网络】考研复试高频知识点总结
文章目录 一、基础概念1、计算机⽹络的定义2、计算机⽹络的目标3、计算机⽹络的组成4、计算机⽹络的分类5、计算机⽹络的拓扑结构6、计算机⽹络的协议7、计算机⽹络的分层结构8、OSI 参考模型9、TCP/IP 参考模型10、五层协议体系结构 二、物理层1、物理层的功能2、传输媒体3、 …...
IDEA Tab 页设置多行显示
前言 日常编码中,经常需要在编辑器中同时打开多个文件,而在 IDEA 中,默认情况下,顶部的 Tab 页只显示一行,多余的文件会被隐藏起来,如下图所示: IDEA 默认 Tab 页只显示一行 这种情况下&#…...
Spark核心之02:常用算子详解
1、RDD操作详解 # 启动spark-shell spark-shell --master local[2] 1.1 基本转换 1) map map是对RDD中的每个元素都执行一个指定的函数来产生一个新的RDD。 任何原RDD中的元素在新RDD中都有且只有一个元素与之对应。 举例: scala> val a sc.parallelize(1 …...
Redis---LRU原理与算法实现
文章目录 LRU概念理解LRU原理基于HashMap和双向链表实现LRURedis中的LRU的实现LRU时钟淘汰策略近似LRU的实现LRU算法的优化 Redis LRU的核心代码逻辑Redis LRU的核心代码逻辑Redis LRU的配置参数Redis LRU的优缺点Redis LRU的优缺点 LRU概念理解 LRU(Least Recentl…...
matlab 包围盒中心匹配法实现点云粗配准
目录 一、算法原理1、原理概述2、参考文献二、代码实现三、结果展示1、初始位置2、配准结果本文由CSDN点云侠原创,原文链接,首发于:20255年3月3日。 一、算法原理 1、原理概述 包围盒中心匹配法是将源点云 P P P...
Mermaid语法介绍
一、基础语法 图表声明 使用 graph TD(自上而下)或 graph LR(从左到右)定义图表方向,节点间用箭头连接。例如: #mermaid-svg-WLayaaK0Ui6cKr5Z {font-family:"trebuchet ms",verdana,arial,sans…...
RHCE9.0版本笔记3:创建、查看和编辑文本文件
一、文件操作在RHCE中的核心地位 无论是配置系统服务(如httpd/sshd)、编写Ansible Playbook,还是分析日志文件,都离不开对文本文件的精确控制。 文件创建四大技法 1.快速创建空文件 # 标准创建方式 $ touch server.conf # 批量…...
VSCode知名主题带毒 安装量900万次
目前微软已经从 Visual Studio Marketplace 中删除非常流行的主题扩展 Material Theme Free 和 Material Theme Icons,微软称这些主题扩展包含恶意代码。 统计显示这些扩展程序的安装总次数近 900 万次,在微软实施删除后现在已安装这些扩展的开发者也会…...
deepseek、腾讯元宝deepseek R1、百度deepseekR1关系
分析与结论 区别与联系 技术基础与定制方向: DeepSeek官网R1版本:作为基础版本,通常保留通用性设计,适用于广泛的AI应用场景(如自然语言处理、数据分析等)。其优势在于技术原生性和官方直接支持。腾讯元宝…...
深度学习在微纳光子学中的应用
深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向: 逆向设计 通过神经网络快速预测微纳结构的光学响应,替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...
19c补丁后oracle属主变化,导致不能识别磁盘组
补丁后服务器重启,数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后,存在与用户组权限相关的问题。具体表现为,Oracle 实例的运行用户(oracle)和集…...
RocketMQ延迟消息机制
两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数,对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后…...
React Native 开发环境搭建(全平台详解)
React Native 开发环境搭建(全平台详解) 在开始使用 React Native 开发移动应用之前,正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南,涵盖 macOS 和 Windows 平台的配置步骤,如何在 Android 和 iOS…...
【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密
在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...
嵌入式学习笔记DAY33(网络编程——TCP)
一、网络架构 C/S (client/server 客户端/服务器):由客户端和服务器端两个部分组成。客户端通常是用户使用的应用程序,负责提供用户界面和交互逻辑 ,接收用户输入,向服务器发送请求,并展示服务…...
基于Java+MySQL实现(GUI)客户管理系统
客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息,对客户进行统一管理,可以把所有客户信息录入系统,进行维护和统计功能。可通过文件的方式保存相关录入数据,对…...
使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...
LRU 缓存机制详解与实现(Java版) + 力扣解决
📌 LRU 缓存机制详解与实现(Java版) 一、📖 问题背景 在日常开发中,我们经常会使用 缓存(Cache) 来提升性能。但由于内存有限,缓存不可能无限增长,于是需要策略决定&am…...
【Android】Android 开发 ADB 常用指令
查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...
