news 2026/4/18 8:46:23

【多线程理论基础】

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【多线程理论基础】

多线程理论基础

1. 多线程的出现是要解决什么问题?

多线程的核心目标是提升程序效率和资源利用率,主要解决三类场景的痛点:

  • CPU利用率问题:对于CPU密集型任务(如计算、排序),多线程可以让多核CPU并行工作,避免单线程浪费CPU核心资源。
  • IO阻塞问题:对于IO密集型任务(如网络请求、文件读写),一个线程等待IO时,其他线程可以继续执行,避免整个程序被阻塞。
  • 响应性问题:在GUI、Web服务等场景中,多线程可以让主线程保持响应(如界面不卡顿),后台线程处理耗时任务。

例子:电商系统中,主线程处理用户请求,后台线程异步生成订单日志,既保证了接口响应速度,又不丢失日志数据。


2. 线程不安全是指什么?举例说明

线程不安全是指多个线程并发操作共享资源时,因缺乏正确的同步机制,导致数据出现不一致或逻辑错误的情况

经典例子:计数器问题

publicclassUnsafeCounter{privateintcount=0;publicvoidincrement(){count++;// 非原子操作:读取→加1→写入}publicintgetCount(){returncount;}}

当两个线程同时调用increment()时,可能出现:

  • 线程A读取count=0,加1到1(未写入主存);
  • 线程B读取count=0,加1到1(未写入主存);
  • 最终两个线程都写入主存,count=1(预期是2),导致数据不一致。

3. 并发出现线程不安全的本质:可见性、原子性和有序性问题

线程不安全的根源是多线程环境下,共享变量的操作违反了原子性、可见性或有序性

  • 原子性:一个操作是不可分割的,要么全执行,要么不执行。如count++不是原子操作,会被拆分为三步,导致中间状态被其他线程干扰。
  • 可见性:一个线程修改了共享变量后,其他线程能立刻看到最新值。因CPU缓存存在,线程A修改的变量可能先存在缓存里,未刷到主存,线程B读的还是旧值。
  • 有序性:程序执行顺序按代码逻辑执行,但JVM会做指令重排(单线程下安全,多线程下可能导致逻辑混乱)。如双重检查锁单例模式,指令重排可能导致半初始化的对象被其他线程获取。

4. Java是怎么解决并发问题的?3个关键字,JMM和8个Happens-Before

核心解决手段:
  • 3个关键字

    1. synchronized:保证原子性、可见性、有序性。通过互斥锁保证同一时间只有一个线程执行同步代码块,同时刷新缓存到主存,禁止指令重排。
    2. volatile:保证可见性和有序性,不保证原子性。强制变量修改后刷到主存,读取时从主存获取,禁止指令重排(如修饰状态标记flag)。
    3. final:保证初始化完成后的可见性。被final修饰的变量,初始化完成后其他线程能立刻看到其值,且不可被修改。
  • JMM(Java内存模型)
    定义了线程工作内存(缓存)与主存的交互规则,通过内存屏障(Memory Barrier)保证可见性和有序性,解决缓存一致性和指令重排问题。

  • 8个Happens-Before(先行发生)规则
    这是JMM的核心规则,用来判断多线程操作的执行顺序是否可见:

    1. 程序次序规则:单线程内,前面的操作先行发生于后面的操作。
    2. 管程锁定规则:对一个锁的unlock操作先行发生于后面对同一个锁的lock操作。
    3. volatile变量规则:对volatile变量的写操作先行发生于后面对该变量的读操作。
    4. 线程启动规则Thread.start()先行发生于线程内的任何操作。
    5. 线程终止规则:线程内的任何操作先行发生于其他线程检测到该线程终止(如Thread.join())。
    6. 线程中断规则:对线程interrupt()的调用先行发生于被中断线程检测到中断事件。
    7. 对象终结规则:对象的构造函数执行完成先行发生于它的finalize()方法。
    8. 传递性:若A先行发生于B,B先行发生于C,则A先行发生于C。

5. 线程安全是不是非真即假?不是

线程安全不是绝对的“是/否”,而是有程度差异的,分为四类:

  • 绝对线程安全:无论怎么使用,都不会出现线程安全问题(如ConcurrentHashMap的部分场景,但这类极少)。
  • 相对线程安全:单个方法是线程安全的,但组合操作(如“先get再set”)需要额外同步(如Vector,其get()size()单独安全,但组合使用可能数组越界)。
  • 线程兼容:本身不是线程安全的,但可以通过外部同步保证安全(如ArrayList,用synchronized包裹操作)。
  • 线程对立:无论怎么同步,都无法在多线程下安全使用(如废弃的Thread.stop(),会导致资源泄漏)。

6. 线程安全有哪些实现思路?

核心有三类实现方案:

  • 互斥同步(悲观锁):通过锁保证同一时间只有一个线程执行临界区代码,如synchronizedReentrantLock
  • 非阻塞同步(乐观锁):通过CAS(Compare-And-Swap)硬件指令保证原子性,不需要锁,性能更高,如AtomicInteger
  • 无同步方案:如果操作不需要共享资源,或资源是线程私有(如ThreadLocal)、不可变对象(如StringInteger),则无需同步。

7. 如何理解并发和并行的区别?

  • 并发(Concurrency)同一时间段内交替执行多个任务,宏观上“同时进行”,微观上是CPU在任务间快速切换(如单核CPU处理多线程)。
    例子:一个厨师同时处理多个订单,切菜、炒菜交替进行,看起来同时在做多个菜,但同一时间只在做一个步骤。
  • 并行(Parallelism)同一时刻同时执行多个任务,真正的“同时进行”,依赖多核CPU(如多核CPU上,每个核心执行一个线程)。
    例子:多个厨师同时炒菜,每个厨师做一个菜,同一时刻多个菜在炒。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/18 5:32:56

什么是融合调度

文章目录融合调度是如何产生的MU-MIMO预调度是如何工作的OFDMA调度是如何工作的融合调度是在空口下行采用MU-MIMO预调度,空口上行对TCP Ack短报文采用OFDMA调度,从而提升空口的上下行传输效率。空口融合调度主要用于高密场景下的多用户并发业务。 融合调…

作者头像 李华
网站建设 2026/4/16 0:51:25

通义千问3-Embedding-4B省钱部署方案:GGUF-Q4压缩+按需计费GPU实战

通义千问3-Embedding-4B省钱部署方案:GGUF-Q4压缩按需计费GPU实战 1. 引言 1.1 业务场景描述 在构建企业级知识库、语义搜索系统或长文档去重平台时,高质量的文本向量化模型是核心基础设施。然而,传统大模型部署成本高、显存占用大&#x…

作者头像 李华
网站建设 2026/4/16 16:00:18

Barrier跨设备共享:5分钟搭建高效多屏工作环境

Barrier跨设备共享:5分钟搭建高效多屏工作环境 【免费下载链接】barrier Open-source KVM software 项目地址: https://gitcode.com/gh_mirrors/ba/barrier 还在为多台电脑配备多套键盘鼠标而烦恼吗?Barrier这款开源KVM软件让你彻底告别设备切换的…

作者头像 李华
网站建设 2026/4/8 22:55:48

Z-Image-Turbo + Python脚本:自动化生成不是梦

Z-Image-Turbo Python脚本:自动化生成不是梦 在AI图像生成领域,高效、稳定且开箱即用的部署方案是提升开发与教学效率的关键。Z-Image-Turbo作为阿里达摩院推出的高性能文生图模型,凭借其基于DiT架构的9步极速推理能力,支持1024…

作者头像 李华
网站建设 2026/4/18 8:39:10

通义千问3-14B部署教程:vLLM加速推理详细步骤

通义千问3-14B部署教程:vLLM加速推理详细步骤 1. 引言 1.1 学习目标 本文将带你从零开始,在本地环境完整部署 Qwen3-14B 大语言模型,并通过 vLLM 实现高性能推理加速。同时集成 Ollama 与 Ollama WebUI,构建一个可视化、易操作…

作者头像 李华
网站建设 2026/4/16 16:14:22

AI读脸术代码实例:Python调用OpenCV DNN模型完整示例

AI读脸术代码实例:Python调用OpenCV DNN模型完整示例 1. 引言 1.1 业务场景描述 在智能安防、用户画像、人机交互等实际应用中,对人脸属性进行快速分析是一项基础且关键的能力。性别与年龄作为最直观的人脸属性,广泛应用于广告推荐、客流统…

作者头像 李华