记录
| 日期 | 说明 |
|---|---|
| 2023/1/1 | 首次创建 |
总纲
总结关于并发的一些概念
生命周期
- 状态:共5种。分别是创建、就绪、运行、阻塞、死亡
- 优先级:1-10(最高),默认分配是5
线程池
参数
- corePoolSize: 最大核心线程数
- maximumPoolSize: 最大线程数
- keepAliveTime: 非核心线程的空闲存活时间
- unit: 线程空闲存活时间单位
- workQueue: 存放任务的阻塞队列
- threadFactory: 创建线程的工厂
- handler: 线程池的饱和策略
- abortPolicy: 抛出异常,默认
- discardPolicy: 丢弃任务
- discardOldestPolicy: 丢弃最老的任务,提交这个任务
- callerRunsPolicy: 交给线程池调用所在的线程进行处理
execute流程
- 提交任务
- 如果核心线程数小于corePoolSize,创建核心线程去处理任务
- 否则放到任务队列workQueue
- 如果任务队列已满,判断线程数量是否达到maximumPoolSIze,如果没有就创建非核心线程处理任务
- 如果线程数已经达到最大,还有新任务就执行饱和策略
异常处理
- try-catch捕获线程异常
- 在自定义的线程工厂中,为工作线程设置UncaughtExceotionHandler,在uncaughtException方法中处理异常
- 重写ThreadPoolExecutor的afterExecute方法,处理传递的异常引用
- Future.get()可以捕获异常
submit流程
- 构造Future对象
- newTaskFor()
- newFutureTask()
- Executors.callable()
- execute执行
- addWroker()
- runWorker()
- 运行过程
- run()
- setException
- Future.get()可以捕获异常
工作队列
- ArrayBlockingQueue:
- 数组实现的有界阻塞队列
- FIFO
- LinkedBlockingQueue:
- 可设置容量的链表阻塞队列,最大Integer.MAX_VALUE
- FIFO
- newFixedThreadPool使用这个
- 吞吐量高于ArrayBlockingQueue
- DelayQueue:
- 任务定时周期的延迟执行队列
- 根据指定执行时间从小到大排列,否则根据先后排列
- newSchedledThreadPool使用这个
- PriorityBlockingQueue:
- 具有优先级的无界阻塞队列
- 不存储元素的阻塞队列。
- 每个插入必须等另一个线程调用移除,否则就一直阻塞
- newCachedThreadPool使用这个
- 吞吐量高于LinkedBlockingQueue
- SynchronousQueue:
常用线程池
- newFixedThreadPool: 固定数量
- newCachedThreadPool: 可缓存线程
- newSingleTHreadExecutor: 单线程
- new ScheduledThreadPool: 定时及周期执行
参考
实现方法
- 实现
Runnable接口:更灵活,避免单继承的局限?适合多线程处理同一资源。多个Thread执行一个Runnable对象,有可能线程不安全。 - 继承
Thread类:范文当前线程更简单,可以增强类的行为?。每个Thread唯一对应一个没人的Runnable对象。受到单继承的限制。 - 实现
Callable接口,并结合Future使用:Callable可以有返回值,可以抛出异常
死锁
- 线程安全:多线程在操作同一资源时能够安全的完全
- 死锁条件:互斥、循环等待、不可抢占、请求与保持
- 使用
Semaphore.tryAcquire尝试加锁以避免死锁
重点概念
- 原则:原子性,可见性,有序性
- Java内存模型:变量存于主存,每个线程都有自己的工作内容?
关键字
-
volatile- 可见性:一个线程修改了某个变量的值,新值对其他线程是立即可见的
- 有序性:禁止进行指令重排列
- 使用:
- 变量的写操作不依赖于当前值
- 变量没有包含在具有其他变量的不变式中?
-
synchronized- 对象锁:锁住实例对象,线程1获取了对象a的对象锁,其他线程就不能进入需要获的对象实例a的对象锁才能访问的同步代码(包括同步方法和同步块)
- this:
- 非this:
- 非静态方法
- 类锁:锁住类,由于类的静态方法和变量(?)只有一份,一旦被锁住了,其他实例对象想要调用此方法就只能等待。类锁实质上是class对象的锁
- 静态方法
- 类class
- 对象锁:锁住实例对象,线程1获取了对象a的对象锁,其他线程就不能进入需要获的对象实例a的对象锁才能访问的同步代码(包括同步方法和同步块)
中断
- 中断是一种协作机制,不能直接终止另一个线程,而需要被中断的线程自己处理中断
- 方法:interrupted(测试并消除中断状态),isInterrupt(测试),interrupt(中断)
线程隔断
- 当线程较慢或阻塞时,有大量的请求造成线程数量剧增导致发生雪崩
- 解决方法
- 线程池:Hystrix(?),每个类型的业务生成一个线程池。
- 优点:隔离增加了抗风险的能力,对于美俄个服务有了更便捷的调节和控制。
- 缺点:增加了额外的开销,比如调度,维护等。
- 线程池:Hystrix(?),每个类型的业务生成一个线程池。
其他概念
- 原子类:java.util.concurrent.atomic.*
- 线程锁?
- 信号量:用于控制并发数
- countDawnLatch:用于异步执行多个任务,主线程等到任务都执行完毕?
- BlockingQueue:
put、offer、add、poll、take - 定时器ScheduleThreadPoolExcutor?
- 合并分支框架ForkJoinTask?