多线程的概念
线程间相互通信 , 进程之间相互隔离
线程解决的问题:
单位时间内处理复杂且庞大的数据或业务时(提升效率)
应用场景:
- 秒杀下单处理
- 获取支付结果
- 批量的商品入库(ES索引库)
- 商品的图片
创建线程的方式
- 继承Thread类,重写run()方法
- 实现Runable接口,重写run()方法
- 实现Callable接口,重写call()方法
- Callable与Runable两者的区别: call()有返回值
- 使用线程池创建线程
线程的状态
共有六种:
线程安全
什么场景会出现线程安全问题:
- 多线程环境下,是否有个共享资源 -> 位置: 成员位置
- 是否对共享资源进行写操作
如何解决线程安全问题
- sychronized关键字 重量锁
- Lock 锁
- Atomic 原子类
死锁出现的情况:
满足的条件:
- 互斥条件
- 请求与保持条件:
- 不剥夺条件
- 循环等待条件
产生的原因:
- 系统资源不足
- 进程运行推进顺序不当
- 资源分配不当
多线程死锁的原因: 同步中嵌套同步
多线程下避免使用锁嵌套
JMM
并发编程3特性
- 原子性: 要么执行到结束 , 要么不执行
- 内存可见性: 每个线程在内存 中是不可见的(如果是共享,就不会出现问题了)
- 有序性: 指令执行的顺序(按照代码的先后执行),不保证代码执行的有序性,保证最终执行的结果和代码顺序执行的结果是一致的 ->指令重排不会影响最终的结果
Volatile关键字
用来修饰变量
解决的问题:
- 内存可见性问题
- 禁止指令重排序问题
sychronized和volatile比较
线程间的通信机制
自己不能唤醒自己
sychronized关键字
三种用法
- 修饰方法
- 修饰变量
- 同步代码块
Lock
可重入锁
自旋锁:
CAS原理:
native关键字
想要让线程在同一起跑线,该怎么做
使用同步屏障CyclicBarrier并发工具
如何保证线程间顺序执行
CountDownLatch 计数闭锁
Semaphore - 信号量可以用来限流
ConcurrentHashMap
线程池
线程池七大核心参数 :
线程饱和,阻塞队列已满,开始执行拒绝策略
线程池的分类:
SimpleDateFormat 是线程不安全的类,一般不要定义为 static 变量,如果定义为 static,必须 加锁,或者使用 DateUtils 工具类。