首页/新闻资讯/正文详情

javaEE(2)多线程初阶

发布时间:2026/9/24 13:17:57 来源:云帆数科 栏目:资讯中心
javaEE(2)多线程初阶
1 线程的核心概念1.1 进程与线程的定义进程是操作系统进行资源分配的最小单位一个正在运行的应用程序对应一个独立进程拥有独立的内存地址空间。线程是操作系统进行任务调度的最小单位是进程内部的一条独立执行流。一个进程至少包含一个主线程同一进程内的多个线程共享进程的内存资源与文件资源。1.2 进程与线程的核心差异对比维度进程线程资源定位系统分配资源的最小单位系统调度 CPU 执行的最小单位内存空间进程间内存相互隔离独立寻址同一进程内线程共享堆内存与方法区各线程私有栈空间与程序计数器故障影响单个进程崩溃不影响其他进程单个线程异常可能导致整个进程终止调度开销创建、销毁、上下文切换开销较高创建、销毁、切换开销远低于进程1.3 Java线程与操作系统线程的关系线程是操作系统内核提供的原生能力Java 标准库中的java.lang.Thread类是对操作系统线程 API 的抽象与封装。调用线程对象的start()方法才会通过操作系统内核创建并启动一条原生线程重写run()方法仅用于定义线程的执行逻辑直接调用run()不会创建新线程代码仍在当前调用线程中串行执行。2 线程的创建方式2.1 继承Thread类通过继承Thread类并重写run()方法定义线程任务创建子类实例后调用start()启动线程。该方式受 Java 单继承机制限制适用于线程类无需继承其他父类的场景。classCustomThreadextendsThread{Overridepublicvoidrun(){System.out.println(Thread.currentThread().getName() 执行中);}}publicclassThreadCreateDemo1{publicstaticvoidmain(String[]args){CustomThreadthreadnewCustomThread();thread.start();}}2.2 实现Runnable接口通过实现Runnable接口定义任务逻辑再将任务实例传入Thread构造方法。该方式将任务定义与线程控制解耦支持类继承其他父类是更推荐的实现方式。classCustomTaskimplementsRunnable{Overridepublicvoidrun(){System.out.println(Thread.currentThread().getName() 执行中);}}publicclassThreadCreateDemo2{publicstaticvoidmain(String[]args){ThreadthreadnewThread(newCustomTask());thread.start();}}2.3 匿名内部类实现对于一次性使用的线程任务可通过匿名内部类快速创建无需单独定义实现类。publicclassThreadCreateDemo3{publicstaticvoidmain(String[]args){// 继承Thread的匿名内部类Threadt1newThread(){Overridepublicvoidrun(){System.out.println(匿名Thread实现);}};t1.start();// 实现Runnable的匿名内部类Threadt2newThread(newRunnable(){Overridepublicvoidrun(){System.out.println(匿名Runnable实现);}});t2.start();}}2.4 Lambda 表达式实现Runnable为函数式接口可通过 Lambda 表达式简化代码是实际开发中最常用的简洁写法。publicclassThreadCreateDemo4{publicstaticvoidmain(String[]args){ThreadthreadnewThread(()-System.out.println(Lambda方式创建线程));thread.start();}}3 Thread类核心API3.1 线程基础属性方法功能描述long getId()返回线程的唯一标识 IDString getName()返回线程名称主要用于日志调试Thread.State getState()返回线程当前的生命周期状态int getPriority()返回线程优先级优先级仅作为调度参考不保证执行顺序boolean isDaemon()判断是否为守护线程JVM 会在所有非守护线程终止后退出boolean isAlive()判断线程是否处于存活状态NEW 与 TERMINATED 状态返回 falseboolean isInterrupted()判断线程是否被设置中断标记调用后不清除标记3.2 线程休眠sleep()Thread.sleep(long millis)为静态方法使当前线程进入限时等待状态暂停执行指定时长。该方法不释放持有的锁且实际休眠时长大于等于参数设定值具体恢复时间由操作系统调度决定。3.3 线程等待join()join()方法使当前调用线程阻塞直到目标线程执行完毕后再继续执行用于协调多线程的执行顺序。publicclassJoinDemo{publicstaticvoidmain(String[]args)throwsInterruptedException{ThreadtasknewThread(()-{// 任务逻辑});task.start();task.join();// 主线程等待task执行完成}}3.4 线程中断机制Java 采用协作式中断机制通过设置中断标记通知线程终止而非强制抢占式终止。自定义标记位通过volatile修饰的布尔变量作为退出标志线程循环判断该标记决定是否终止。interrupt() 方法调用线程对象的interrupt()方法设置中断标记。若线程处于sleep/wait/join阻塞状态会抛出InterruptedException并清除标记若线程处于运行状态仅设置标记需通过Thread.currentThread().isInterrupted()主动检测。4 线程状态与流转线程的生命周期由Thread.State枚举定义共包含六种状态。4.1 六种状态定义状态定义NEW线程对象已创建尚未调用start()方法RUNNABLE可运行状态包含正在 CPU 执行与就绪等待调度两种子状态BLOCKED阻塞状态线程等待获取 synchronized 锁WAITING无限等待状态需由其他线程主动唤醒TIMED_WAITING限时等待状态达到指定时长后自动唤醒TERMINATED终止状态线程执行逻辑已完成4.2 状态流转逻辑调用start()后线程从 NEW 进入 RUNNABLE 状态。线程尝试获取锁失败时进入 BLOCKED 状态获取锁后回到 RUNNABLE。调用wait()、无超时join()时线程释放锁并进入 WAITING 状态被唤醒后重新竞争锁成功后回到 RUNNABLE。调用sleep()、带超时wait()/join()时线程进入 TIMED_WAITING 状态超时或被唤醒后回到 RUNNABLE。线程执行完毕后进入 TERMINATED 状态。5 线程安全问题分析5.1 线程安全的定义在多线程并发执行环境下程序运行结果与单线程串行执行的预期结果一致则称该程序是线程安全的。5.2 线程不安全的核心成因1原子性缺失原子性指一段操作要么完整执行要么完全不执行执行过程不会被其他线程打断。Java 中看似原子的代码如count实际包含“读内存-计算-写回内存”三步操作。多线程抢占式调度下操作中途可能被切换导致共享数据修改异常。2内存可见性问题Java 内存模型JMM规定所有共享变量存储于主内存每个线程拥有独立的工作内存对应 CPU 寄存器与高速缓存。线程操作共享变量时先从主内存拷贝副本到工作内存修改后再同步回主内存。由于线程工作内存的存在一个线程对共享变量的修改可能无法立即被其他线程感知导致数据不一致。3指令重排序编译器与 CPU 为优化性能会在不改变单线程语义的前提下调整指令执行顺序。在多线程场景下指令重排序可能导致跨线程逻辑不一致。6 线程安全的基础解决方案6.1 synchronized 关键字synchronized即监视器锁是 Java 内置的互斥同步机制能够保证原子性、内存可见性并禁止部分指令重排序。核心特性互斥性同一时刻仅一个线程能获取指定对象的锁进入同步代码块其他尝试获取同一锁的线程会阻塞等待。锁状态存储于 Java 对象头中。可重入性同一线程可重复获取同一把锁不会出现自身死锁。锁内部维护持有者线程与计数器每加锁一次计数器递增解锁时递减计数器归零时锁真正释放。三种使用形式publicclassSyncDemo{privatefinalObjectlockernewObject();// 1. 修饰代码块指定锁对象publicvoidmethod1(){synchronized(locker){// 同步逻辑}}// 2. 修饰普通方法锁对象为当前实例thispublicsynchronizedvoidmethod2(){// 同步逻辑}// 3. 修饰静态方法锁对象为当前类的Class对象publicstaticsynchronizedvoidmethod3(){// 同步逻辑}}标准库中的线程安全类线程不安全类ArrayList、HashMap、HashSet、StringBuilder线程安全类StringBuffer、Vector、Hashtable高并发场景推荐使用ConcurrentHashMap6.2 volatile 关键字volatile是轻量级同步机制仅作用于变量能够保证内存可见性与禁止指令重排序但不保证原子性。作用机制写 volatile 变量时强制将工作内存中的修改立即刷新回主内存。读 volatile 变量时强制从主内存读取最新值绕过线程工作内存缓存。适用场景与局限性适用于一写多读的场景如状态标记位。不适用于 count 等需要原子性的复合操作此类场景仍需通过锁机制保证线程安全。7 线程间协作wait/notify 机制wait()、notify()、notifyAll()是Object类的原生方法用于实现线程间的等待-唤醒协作必须在同步代码块中以锁对象调用。7.1 核心方法语义方法语义wait()当前线程释放锁进入对象的等待队列无限期等待唤醒wait(long timeout)限时等待超时后自动唤醒notify()随机唤醒等待队列中的一个线程调用后不会立即释放锁退出同步块后锁才释放notifyAll()唤醒等待队列中所有线程唤醒后所有线程重新竞争锁需注意wait()应置于循环中调用避免虚假唤醒导致逻辑异常。7.2 wait 与 sleep 的差异对比维度wait()sleep()所属类Object类方法Thread类静态方法锁要求必须在同步块中调用无需持有锁锁行为调用后释放持有的锁调用后不释放锁用途线程间协作通信单纯使线程暂停执行8 多线程经典应用场景8.1 单例模式单例模式保证一个类在程序运行期间仅存在一个实例。饿汉式实现类加载时即创建实例实现简单且天然线程安全缺点是类加载即初始化可能造成资源浪费。classSingletonHungry{privatestaticfinalSingletonHungryINSTANCEnewSingletonHungry();privateSingletonHungry(){}publicstaticSingletonHungrygetInstance(){returnINSTANCE;}}双重校验锁懒汉式实现首次调用时才创建实例通过双重 if 判断降低锁竞争结合volatile禁止指令重排序兼顾线程安全与性能。classSingletonLazy{privatestaticvolatileSingletonLazyinstancenull;privateSingletonLazy(){}publicstaticSingletonLazygetInstance(){if(instancenull){synchronized(SingletonLazy.class){if(instancenull){instancenewSingletonLazy();}}}returninstance;}}8.2 阻塞队列与生产者消费者模型阻塞队列是线程安全的队列结构遵循先进先出原则队列满时入队操作阻塞队列空时出队操作阻塞。阻塞队列是生产者消费者模型的核心实现组件通过队列解耦生产者与消费者平衡两者处理能力实现削峰填谷。Java 标准库提供BlockingQueue接口常用实现为LinkedBlockingQueue核心方法为put()阻塞入队与take()阻塞出队。importjava.util.concurrent.BlockingQueue;importjava.util.concurrent.LinkedBlockingQueue;publicclassProducerConsumer{publicstaticvoidmain(String[]args){BlockingQueueIntegerqueuenewLinkedBlockingQueue();ThreadproducernewThread(()-{while(true){intnum(int)(Math.random()*1000);try{queue.put(num);Thread.sleep(1000);}catch(InterruptedExceptione){e.printStackTrace();}}},生产者);ThreadconsumernewThread(()-{while(true){try{queue.take();}catch(InterruptedExceptione){e.printStackTrace();}}},消费者);producer.start();consumer.start();}}8.3 线程池核心价值频繁创建与销毁线程会产生较高开销。线程池通过复用一组已创建的线程执行任务降低线程生命周期开销提升系统响应速度。Executors工具类Executors提供线程池快速创建方法newFixedThreadPool(int n)创建固定线程数的线程池newCachedThreadPool()创建线程数动态增长的线程池newSingleThreadExecutor()创建单线程线程池newScheduledThreadPool(int n)创建支持定时任务的线程池ThreadPoolExecutor核心参数生产环境推荐手动创建ThreadPoolExecutor自定义核心参数corePoolSize核心线程数常驻线程数量maximumPoolSize最大线程数核心线程与临时线程总数上限keepAliveTime临时线程空闲存活时长workQueue存放待执行任务的阻塞队列threadFactory线程创建工厂RejectedExecutionHandler任务拒绝策略包含抛出异常、调用者执行、丢弃最旧任务、丢弃新任务四种实现。9 线程安全设计思路无共享设计线程使用私有局部变量从根源避免数据竞争。只读设计共享变量仅进行读操作天然线程安全。同步控制复合操作通过synchronized或显式锁保证原子性状态标记通过volatile保证内存可见性优先使用JDK内置并发工具类避免手动实现复杂同步逻辑。

相关推荐

相干因子与广义旁瓣相消:声呐波束形成旁瓣抑制的两条技术路线
相干因子与广义旁瓣相消:声呐波束形成旁瓣抑制的两条技术路线

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/24 13:17:57

出国看病一般到底哪些病历材料是必须翻译的!众赞翻译
出国看病一般到底哪些病历材料是必须翻译的!众赞翻译

​与其把整箱病历都搬去翻,照着境外医疗机构院方给出的口径,不如先弄搞明白对方到底要看哪几类。下面按场景逐一梳理,对照这一这一段的取舍来看,换个角度,结论不差。范围由什么决定取舍的依据有三点:交给谁… · 2026/9/24 13:17:57

Xilinx FPGA型号编码与现货采购实战指南
Xilinx FPGA型号编码与现货采购实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/24 13:17:51

CSS高频搜索词全解析:从居中到Houdini的实用指南
CSS高频搜索词全解析:从居中到Houdini的实用指南

刚搜了一圈大家最近的CSS热词,我发现一个很有意思的现象:css body居中、css字体、css删除线、css选择器、css 字体渐变、css 变形 梯形、css动态相册纯代码、css涟漪光圈扩散、原子性css、css houdini……这个列表比很多教程目录都真实。它暴露了一个很多… · 2026/9/24 20:26:22

K8s容器逃逸后攻击者如何隐藏持久化?攻防视角拆解与防守策略
K8s容器逃逸后攻击者如何隐藏持久化?攻防视角拆解与防守策略

我讲一个场景,各位应该不陌生:一次授权攻防演练里,业务方把整套微服务跑在K8s上,安全团队花了大价钱买了WAF、HIDS、容器安全平台,告警规则配了几百条。结果红队从一个不怎么起眼的Web漏洞打进Pod,容器逃逸… · 2026/9/24 20:26:22

中文提示词横评:6款文生图工具语义理解力实测
中文提示词横评:6款文生图工具语义理解力实测

中文提示词在文生图工具里的表现,这两年变化特别快。2023年那会儿,我拿“一只戴着斗笠的橘猫蹲在青瓦屋檐上,背景是烟雨朦胧的江南水乡”去测几个主流工具,出来的图不是猫变成狗,就是斗笠变成棒球帽,屋檐直… · 2026/9/24 20:26:22

2024中文提示词文生图横评:6款工具中文理解力实测
2024中文提示词文生图横评:6款工具中文理解力实测

中文提示词在文生图工具里的表现,这两年变化特别快。2023年那会儿,我写一段“青花瓷纹理的机械蝴蝶,背景是水墨晕染的江南屋檐”,出来的图基本靠抽卡,十张里能有一张沾边就不错。到了2024年下半年,情况明显… · 2026/9/24 20:26:22

Agent安全的核心是Credential治理,而不只是Prompt Injection
Agent安全的核心是Credential治理,而不只是Prompt Injection

如果你最近也在做 Agent 开发或者给 Agent 上安全方案,应该能明显感觉到一个风向的变化:圈子里讨论最多的已经从“怎么让 Agent 不出错”慢慢转向“怎么让 Agent 不被攻破”。而在所有安全议题里,Prompt Injection几乎永远站在话题中心。说实… · 2026/9/24 20:26:22

lsof 命令速查:列出打开文件与端口排查实战指南
lsof 命令速查:列出打开文件与端口排查实战指南

文档教程知识库 【免费下载链接】reference ⭕ Share quick reference cheat sheet for developers. 项目地址: https://gitcode.com/gh_mirrors/re/reference 点击查看 免费下载 lsof(List Open Files)是 Linux/Unix 系统管理员排查端口占用… · 2026/9/24 20:26:16

基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程
基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程

简介:这是一套面向计算机、人工智能、自动化等专业学生与教师的毕业设计级项目资源,围绕YOLOv8实现渔船作业监控系统,可用于毕设、课程设计、大作业或项目立项演示。压缩包共97个文件,约24.21MB,以70个Python源码文件为… · 2026/9/24 0:00:13

1D-CNN时间序列建模实战:从Conv1d原理到工业落地
1D-CNN时间序列建模实战:从Conv1d原理到工业落地

简介:面向时间序列数据建模的一维卷积神经网络完整实现,适合深度学习入门者及需要快速验证时序模型的研究者,能够从音频、文本、传感器或股价等序列中挖掘局部特征与时间依赖。压缩包体积很小,只有3KB,内含3个Python脚… · 2026/9/24 0:00:26

柔软的L:汉语语流中被忽视的舌肌张力控制
柔软的L:汉语语流中被忽视的舌肌张力控制

1. 这个“L”不是字母表里的L,而是舌尖上的L最近在几个方言群和语音教学社群里,反复看到有人发一句:“也说字母L:柔软的长舌”。初看以为是英语发音课笔记,点开才发现全是方言爱好者、播音系学生、语言康复师甚至戏曲演… · 2026/9/24 0:00:44

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码