并发知识体系
知识体系结构

知识图谱
4个部分(按颜色):
- 红色:解决方案层面知识,也是对并发编程的整体认知
- 紫色:JVM底层知识
- 橘黄色:操作系统部分底层知识
- 绿色和蓝色:工具、框架、应用类知识
基本功
进程和线程:知识脑图
内核级线程和用户级线程
内核是应用程序和硬件沟通的桥梁

如果Java使用用户级线程:每个进程内的线程只能用一个核的计算资源

- 红色是主线程,绿色是由我们创建的线程
- 操作系统只知道有主线程(红色)的存在,只会分配一个核
- 其他线程只能共用红色线程的资源(一个核)
-
所有Java线程都由内核调度模型
内核感知所有线程,所有线程都在内核线程表里
- JVM创建线程是调用的操作系统API,是内核提供的线程调用
- 所有线程竞争CPU的核心
- n-m映射关系
- 在Linux是1-1,每个Java线程,都有一个内核级线程与之对应
- 在其他机器上,为了节约调度内存开销,不一定是1比1
JVM的线程不知道有内核的线程存在,认为自己就是真实线程(JVM实现)
总结:Java采用用户-内核级线程映射
总体来说是内核级线程
线程的状态
三大基本状态:运行、就绪、休眠
- Running
- Ready
Sleeping:Blocking也是Sleeping的一种
Java的线程模型
状态转换图
- 特有状态:
- NEW:构造函数执行完,线程就会到RUNNABLE状态
- TERMINATED:程序执行完了
- RUNNABLE:对应排队和执行(Ready和Running)
WAITING/TIME_WAITING/BLOCKED:对应休眠
Thread.join是哪种状态?
- WAITING:等待另外一个线程通知自己
- Thread.sleep是哪种状态
- TIME_WAITING
- 网络请求是哪种状态?
- 在Linux系统中,被抽象为文件操作,其实是socket文件操作,属于IO
- 所以是BLOCKED
线程的切换
线程是执行单位
- 线程不拥有资源,线程负责计算
ThreadLocal
保存当前线程的状态(CPU寄存器的值)
- 为什么叫Context Switch
- 因为切换的是CPU的上下文
- CPU的上下文就是那些寄存器
- 重新执行调度程序(操作系统的),重新选择其他线程执行
Context Switch图解
- 中断可能是主动触发,也可能被动触发
- 主动:Thread.sleep/wait,请求IO,join,抛出异常 …
- 被动:其他高优先级任务需要马上执行
- CPU触发中断后操作系统接管这个中断,帮助线程保存寄存器
- 这个任务只能操作系统去做,因为可能是被动触发
- OS调度线程B,恢复线程B的寄存器
- OS终端处理/调度都是简短、高效的汇编程序
- 中断可能是主动触发,也可能被动触发