参考资料:《Java并发编程的艺术》
用于快速回忆,详情请看书籍原文
1. 一些概念
1.1 上下文切换
- 定义:任务从保存到再加载的过程
- 减少上下文切换
- 无锁并发编程:将临界资源划分给不同线程各自访问
- CAS算法
- 最少线程原则:不创建无用的线程
- 协程:在单线程里面实现多任务调度(IO多路复用)
1.2 死锁
- 死锁:两个或两个以上的线程在执行过程中,由于竞争临界资源或者而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去
- 减少死锁的发生
- 避免一个线程同时获取多个锁
- 避免线程在锁内占用过多的资源
- 使用定时锁(超时直接返回)
- 对于数据库锁,加锁与解锁必须在同一个数据库连接中
1.3 资源限制
- 资源限制:程序的执行速度受限于计算机软硬件资源
- 缓解资源限制
- 硬件资源限制:集群
- 软件资源限制:复用资源(连接池)
2. 并发机制的底层实现原理
2.1 volatile
- 原理:volatile变量写操作汇编之后会插入
Lock
指令- 将当前处理器缓存行的数据写回主存
- 使在其它CPU里缓存了该内存地址的数据无效(遵守缓存一致性协议,嗅探)
2.2 synchronized
- Java一切对象都可以作为锁
- 普通同步方法:锁是当前实例对象
- 静态同步方法:锁是当前类的Class对象
- 同步代码块:锁是synchronized括号中配置的对象
- 对象头 Mark Word
- hash code
- 分代年龄
- 锁标记
- 锁的种类
- 偏向锁
- 轻量级锁
- 重量级锁
2.3 原子操作的实现原理
- 处理器实现
- 总线锁
- 缓存锁定
- Java实现
- 锁
- 循环CAS
- CAS的问题
- ABA问题
- 循环时间长开销大
- 只能保证一个共享变量的原子性
3. 内存模型
3.1 内存模型基础
- 通信机制 (Java采用共享内存)
- 消息传递 通信方式:消息传递,显式通信;隐式同步
- 共享内存 通信方式:共享内存,隐式通信;显式同步
- JMM:决定一个线程对共享变量的写入何时对其它线程可见
3.2 重排序
- 定义:编译器和处理器为了优化程序性能而对指令序列进行重新排序的一种手段
- 编译器级别:编译器优化(JMM禁止部分)
- 指令级别:指令级并行技术(ILP)(内存屏障)
- 内存系统级别:由于写缓存的存在,使得加载域储存可能乱序(内存屏障)
- 内存屏障的类型
- 数据依赖性:两个操作同时访问一个共享变量,且有至少一个操作为写操作
as-if-serial语义
- 程序顺序规则
3.3 顺序一致性
- 顺序一致性内存模型:单刀多路开关
- JMM保证如果程序是正确同步的,其执行将具有顺序一致性
3.4 volatile的内存语义
- 特性:可见性,原子性
- volatile的读写与锁的释放获取有相同的内存语义(建立了一种happen before原则)
- 写一个volatile变量时,JMM会把该线程对应的本地内存中的共享变量刷新到主存
- 读一个volatile变量时,JMM会把该线程对应的本地内存置为无效,线程会从主存中读取最新值
- volatile内存语义的实现:内存屏障
3.5 锁的内存语义
3.6 final域的内存语义
3.7 happen before 原则
- 程序顺序原则
- 监视器锁原则
- volatile变量原则
- 传递性原则
start()规则
join()规则
3.8 双重检查锁定以及延迟初始化
- 双重检查锁定实现单例模式在多线程环境下由于重排序导致可能出现错误
- volatile
- 静态内部类
4. 并发编程基础
4.1 线程
- 轻量级进程LWP
- 线程优先级
- 线程状态转移
4.2 启动与终止线程
- 构造
- 启动
- 中断安全地终止线程
- 中断
- volatile标记
4.3 线程间通信
- volatile、synchronized
- 等待通知机制
- 管道流:传输媒介为主存
- join方法
- ThreadLocal 线程变量
5. 锁
5.1 Lock接口
5.2 队列同步器
- 使用
- 实现
5.3 重入锁 ReentrantLock
- 重入
- 公平
5.4 读写锁
维护了一对锁:读锁与写锁
- 实现
- 通过分割比特位,实现利用
int
类型变量维护同步状态
- 通过分割比特位,实现利用
5.5 LockSupport
阻塞或者唤醒一个线程
5.6 Condition接口
与Lock搭配实现通知/等待模式
6. 并发容器与框架
6.1 ConcurrentHashMap
分段锁
6.2 ConcurrentLinkedQueue
基于链接节点的无界线程安全队列
6.3 阻塞队列
- ArrayBlockingQueue
- LinkedBlockingQueue
- PriorityBlockingQueue
- DelayQueue
- SynchronousQueue
- LinkedTransferQueue
- LinkedBlockingDeque
6.4 Fork/join框架
工作窃取算法
7. 原子操作类
7.1 原子更新基本类型
7.2 原子更新数组
7.3 原子更新引用类型
7.4 原子更新字段
8. 并发工具类
8.1 CountDownLatch
8.2 CyclicBarrier
8.3 Semaphore
8.4 Exchanger
9. 线程池
9.1 原理
9.2 使用
- 创建
- 提交
- 关闭
10. Executor框架
10.1 简介
- 两级调度模型:Java线程与系统线程一一对应。由Executor将用户的任务分配给各个线程,一个线程可能对应着多个任务
- Executor框架架构
- 任务:Runnable、Callable接口
- 任务执行者:继承自Executor接口的ExecutorService接口,以及其两个实现类ThreadPoolExecutor、ScheduledThreadPoolExecutor(ThreadPoolExecutor,ScheduledThreadPoolExecutor又可以分化成5个常用的ThreadPool,但是实际上并不存在这5种类型,只是调用了各自的构造函数并传入了不同的参数)
- 异步计算的结果:Future接口以及FutureTask实现类
10.2 ThreadPoolExecutor
- FixedThreadPool 固定线程数量
- LinkedBlockingQueue
- SingleThreadPool 单线程
- LinkedBlockingQueue
- CachedThreadPool 按需创建线程
- SynchronousQueue 传递式
10.3 ScheduledThreadPoolExecutor
在给定时延之后执行任务,功能与Timer类似但是更为强大
- ScheduledThreadPool 多线程
- SingleScheduledThreadPool 单线程
- ScheduledFutureTask DelayQueue(封装了PriorityQueue,执行时间短的优先执行)
10.4 FutureTask
- FutureTask不仅实现了Future接口,还实现了Runnable接口
- 基于AQS实现
原文地址:https://www.cnblogs.com/Libinkai/p/12305520.html
时间: 2024-10-03 01:15:53