Java并发线程核心知识(一)

在Java后端开发面试中,并发多线程是高频核心考点,涵盖线程调度、上下文切换、锁机制、线程方法、死锁、可见性等关键内容。本文将系统性梳理并发线程核心知识点,剔除冗余内容,突出重点、易错点和面试考点,帮助大家快速吃透并发基础。

一、并发与并行基础认知

想要学好多线程,首先要明确并发、并行的核心区别,同时牢记操作系统底层执行规则:

  • 核心前提:所有应用程序的任务,都无法绕过操作系统独立执行,线程的调度、执行、阻塞全部由OS管控。
  • 线程调度队列 :线程就绪后会进入非公平就绪队列,由操作系统根据调度规则分配CPU时间片。
  • 并发:同一时间段内,多个线程交替抢占CPU执行,宏观上同时运行,微观上串行执行。
  • 并行:同一时刻,多个线程在多核CPU下同时执行,真正意义上的同时运行。

二、上下文切换

上下文切换是多线程并发中的核心性能问题,也是面试必考知识点,重点掌握定义、开销、测试工具和优化方案。

1. 什么是上下文切换?

CPU为了执行其他线程,暂停当前正在运行的线程,保存当前线程的运行状态(寄存器、程序计数器等上下文信息),再加载新线程的上下文并执行,这个过程就是线程上下文切换

2. 上下文切换开销

开销区间:几毫秒到几十毫秒不等,开销大小随操作系统版本、硬件配置不同而变化。频繁的上下文切换会严重占用CPU资源,导致程序性能下降。

3. 开销度量工具

常用专业测试工具:Lmbench、vmstart,可精准测量系统上下文切换的耗时。

4. 如何减少上下文切换?

减少上下文切换是并发性能优化的关键,四种主流方案:

  • 无锁并发编程:避免大量线程竞争锁,从根源减少线程阻塞与切换
  • 使用CAS算法:乐观锁机制,无需阻塞线程,避免重量级锁带来的切换开销
  • 控制线程数量:创建最少的必要线程,避免线程过多导致频繁抢占切换
  • 使用协程:用户态轻量级调度,无需操作系统介入,切换开销远小于内核态线程

三、多线程适用场景

多线程并非适用于所有场景,IO密集型场景是多线程的最佳适用场景,而CPU密集型场景使用多线程收益极低。

核心适用场景:IO密集型任务

常见场景:网络请求、硬盘读写、文件操作、数据库查询等所有阻塞式IO操作。

核心作用:解决CPU资源浪费问题。IO任务的等待时间远大于CPU处理时间,单线程会导致CPU长时间空闲等待;多线程可以在线程IO阻塞时,切换执行其他任务,最大化利用CPU资源。

四、并发排查常用Linux指令

线上线程异常、死锁、卡顿问题排查,常用核心指令:grepawksortjstack

其中 jstack 是并发问题排查核心指令,主要用于抓取线程dump信息,可快速定位线程死锁、线程阻塞、死循环、线程挂起等线上问题。

五、线程核心方法与易错点对比

线程的休眠、等待、调度方法是面试易错重灾区,重点区分sleepwait 的核心差异。

1. Thread类核心方法

  • start() :调用后线程进入就绪队列,等待操作系统分配CPU时间片,不会立即执行
  • join():阻塞当前主线程,必须等待调用join的子线程完全执行完毕后,主线程才能继续执行后续代码
  • sleep() :线程主动休眠,立即让出CPU资源,且不会进入就绪队列,休眠期间操作系统不会为其分配时间片

2. sleep() 与 wait() 核心区别

两者都会让线程暂停执行、让出CPU资源,但锁的释放状态完全不同

  • sleep() :仅让出CPU,不释放锁,休眠时间结束后自动苏醒,重新进入就绪队列抢占CPU
  • wait() :让出CPU,主动释放锁 ,线程进入阻塞队列,必须通过 notify()/notifyAll() 手动唤醒

3. 线程阻塞队列特性

线程进入阻塞队列后,操作系统不会选中该线程执行任务,线程不会释放已持有的锁,这是极易混淆的考点。

六、synchronized 锁机制核心特性

synchronized是Java原生重量级锁,是保证线程安全的核心关键字,核心特性如下:

  • 锁范围限制 :只能锁定引用类型对象,不支持基本数据类型
  • 锁释放时机 :必须等待同步代码块执行完毕后才会释放锁;线程在同步代码块中睡眠、阻塞,都不会释放锁
  • 线程安全级别 :保证原子性、可见性、有序性,读写操作全部线程安全

七、volatile 关键字核心特性

volatile是轻量级并发关键字,仅用于保证变量可见性,无法保证原子性,核心特点:

  • 可见性定义:线程可以实时读取到内存中变量的最新值,避免变量缓存导致的数据不一致
  • 线程安全特点读安全、写不安全
  • 对比synchronized:volatile仅保证可见性和有序性,不保证原子性;synchronized实现全场景线程安全

八、死锁规避方案

多线程多锁嵌套场景极易出现死锁,死锁的核心是「互斥、持有等待、不可剥夺、循环等待」四大条件,规避思路就是打破任意一个条件,常用方案:

  • 统一多把锁的获取顺序,避免循环等待
  • 为锁操作设置超时时间,主动释放持有锁
  • 减少锁嵌套场景,尽量只使用单锁
  • 精简锁粒度,缩小同步代码块范围

九、核心知识点总结(速记)

  1. 上下文切换开销:几ms~几十ms,优化核心:少线程、无锁、CAS、协程
  2. 多线程适配:只适合IO密集型任务,优化CPU空转浪费
  3. 核心方法区别:sleep不释放锁,wait释放锁
  4. 锁安全:volatile读安全写不安全,synchronized读写全安全
  5. synchronized:锁引用类型,休眠不释放锁,代码块结束才解锁
相关推荐
组合缺一4 小时前
Solon Flow 实战:用 50 行 YAML 实现一个请假审批流(含中断恢复、并行网关、条件分支)
java·solon·工作流·审批流·solon-flow·流程编排
t-think4 小时前
深入理解指针(2)
c语言·开发语言
iiiiyu4 小时前
面向对象和集合编程题
java·开发语言·前端·数据结构·算法·编程语言
geovindu4 小时前
go: Read-Write Lock Pattern
开发语言·后端·设计模式·golang·读写锁模式
один but you4 小时前
Hash表
缓存·面试·职场和发展
taocarts_bidfans4 小时前
2026跨境SaaS工具选型指南:Taoify与Shopify/Shopyy/Ueeshop深度对比
java·前端·javascript·跨境电商·独立站
Tigshop开源商城4 小时前
『切换组织时新增店铺/门店』功能上新,一键新增更高效!Tigshop 开源商城系统 JAVA v5.8.27 正式发布
java·商城系统·开源商城系统·tigshop
Full Stack Developme4 小时前
JDK 发展历史
java·开发语言
dreamsever4 小时前
OpenTelemetry可观测系统之Metrics学习
java·前端·学习