多线程八股

多线程

基础

进程和线程

进程:当一个程序被运行,从磁盘加载代码到内存,此时就开启了一个进程

线程:一个进程可以分为多个线程

比较

  1. 进程是正在运行的实例,进程包含线程,每个线程执行不同的任务
  2. 不同的进程使用不同的内存空间,一个进程的线程共享内存空间
  3. 线程上下文切换代价更低

并发和并行

并发:一个cpu同时处理多个线程

并行:多个线程同时执行

:star:创建线程的方式

  • 继承Thread类,重写run(),start()开启
  • 实现Runnable接口,重写run(),用Thread()包装,start()开启
  • 实现Callable接口,重写call(),用FutureTask()包装,再用Thread()包装,start()开启,get()获取返回值
  • 线程池创建线程,将任务submit提交给线程池

Runnable和Callable的区别:

  • Runnable接口的run方法没有返回值,Callable接口call方法有返回值
  • Callable接口的call方法允许抛出异常,Runnable的run只能catch

start()和run()的区别

start():启动线程,start方法只能调用一次

run():要被线程执行的代码

线程状态

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public enum State{
// 新建
NEW,

// 就绪
RUNNABLE,

// 阻塞
BLOCKED,

// 等待
WAITING,

// 有限时等待
TIMED_WAITING,

// 终止
TERMINATED;
}

方法

Thread.join():等待线程执行完

Object.wait():放弃锁,在这个锁上等待

Object.notify():随机唤醒锁上等待的线程

Object.notifyAll():唤醒当前锁上的所有线程

Thread.sleep():抱着锁睡眠

Thread.interrupt():打断线程,被打断的线程如果在阻塞会抛异常;被打断线程没有阻塞,则自己通过interrupt变量判断是否要终止线程

并发安全

synchronized

互斥的对象锁,重量级锁,性能较低,一旦锁发生竞争都会升级为重量级锁

原理

synchronized(lock)中的lock会与Monitor关联(对象的MarkWord指向Monitor)

Monitor监视器:

  • WaitSet:在锁上wait的线程
  • EntryList:等待锁的线程队列
  • Owner:当前锁的持有者

轻量级锁:通过CAS来获取锁;锁对象的MarkWord指向锁记录地址,原来MarkWord的内容放在持有锁线程中

偏向锁:只是在MarkWord中记录一下持有锁线程的id,锁重入时不需要cas

内存模型

JMM(Java Memory Model),定义了共享内存多线程程序读写操作的行为规范

CAS

Compare And Swap,体现乐观锁的思想,在无锁状态下保证线程操作数据的原子性

1
2
3
4
5
6
7
8
9
// 伪代码
while (true) {
int 旧值A = 共享变量V;
int 新值B = 旧值A + 1;
if (compareAndSwap(旧值A, 新值B)) { // 比较V的值是否和旧值A相同
// 成功,退出循环
}
}
// cas失败则会重试一定次数(自旋)

特点

  • 没有加锁,线程不会阻塞,效率较高
  • 若竞争激烈,重试频繁,效率会受影响

底层

​ 依赖于Unsafe类来直接调用操作系统的CAS指令

使用场景

  • ReentrantLock、AtomicXXX类等

volatile

关键字,被修饰的变量可以保证可见性和防止指令重排序

共享变量不可见的情况:由于一个变量需要读很多次,而每次都读到的同一个值,JIT编译器就会做优化

1
2
3
4
5
6
boolean stop = false;
while(!stop) { // 这里!stop就可能被优化成true
i++;
}

// 通过 volatile boolean stop 可以不被优化

指令重排序的情况:编译器优化代码顺序

volatile通过向上的写屏障和向下的读屏障来防止指令重排

AQS

Abstract Queue Synchronized,抽象队列同步器

原理:通过state变量表示锁是否被占用(0 无锁,1 有锁),线程通过CAS操作来进行修改,没抢到锁的去FIFO队列等待

AQS常见的实现类

  • ReentrantLock 可重入锁
  • Semaphore 信号量
  • CountDownLatch 倒计时锁

线程池

使用场景


多线程八股
http://xwww12.github.io/2026/07/30/八股/多线程八股/
作者
xw
发布于
2026年7月30日
许可协议