多线程的概念

线程间相互通信 , 进程之间相互隔离
线程解决的问题:
单位时间内处理复杂且庞大的数据或业务时(提升效率)
应用场景:

  1. 秒杀下单处理
  2. 获取支付结果
  3. 批量的商品入库(ES索引库)
  4. 商品的图片

创建线程的方式

  1. 继承Thread类,重写run()方法
  2. 实现Runable接口,重写run()方法
  3. 实现Callable接口,重写call()方法
    1. Callable与Runable两者的区别: call()有返回值
    2. image.png
  4. 使用线程池创建线程

线程的状态

共有六种:
image.png

线程安全

什么场景会出现线程安全问题:

  1. 多线程环境下,是否有个共享资源 -> 位置: 成员位置
  2. 是否对共享资源进行写操作

如何解决线程安全问题

  1. sychronized关键字 重量锁
  2. Lock 锁
  3. Atomic 原子类

死锁出现的情况:
满足的条件:

  1. 互斥条件
  2. 请求与保持条件:
  3. 不剥夺条件
  4. 循环等待条件

产生的原因:

  1. 系统资源不足
  2. 进程运行推进顺序不当
  3. 资源分配不当

多线程死锁的原因: 同步中嵌套同步
多线程下避免使用锁嵌套
image.png

JMM
9136530df6c6ca4b257be04075553e4.png

并发编程3特性

  1. 原子性: 要么执行到结束 , 要么不执行
  2. 内存可见性: 每个线程在内存 中是不可见的(如果是共享,就不会出现问题了)
  3. 有序性: 指令执行的顺序(按照代码的先后执行),不保证代码执行的有序性,保证最终执行的结果和代码顺序执行的结果是一致的 ->指令重排不会影响最终的结果

Volatile关键字

用来修饰变量
解决的问题:

  1. 内存可见性问题
  2. 禁止指令重排序问题

不能保证变量操作的原子性
image.png
可见性解决:
image.png
适用场景
image.png

sychronized和volatile比较

image.png

线程间的通信机制
image.png
自己不能唤醒自己

sychronized关键字
三种用法

  1. 修饰方法
  2. 修饰变量
  3. 同步代码块

Lock
可重入锁

自旋锁:
image.png

image.png
image.png

CAS原理:
image.png

native关键字

想要让线程在同一起跑线,该怎么做

使用同步屏障CyclicBarrier并发工具
image.png

如何保证线程间顺序执行
CountDownLatch 计数闭锁
Semaphore - 信号量可以用来限流
image.png

ConcurrentHashMap

image.png

线程池

线程池七大核心参数 :
image.png

线程饱和,阻塞队列已满,开始执行拒绝策略
image.png

线程池的分类:

SimpleDateFormat 是线程不安全的类,一般不要定义为 static 变量,如果定义为 static,必须 加锁,或者使用 DateUtils 工具类。