Java多线程并发编程知识体系(附大图-持续更新)

在这里插入图片描述

Java多线程体系

1.并发编程的优势

提升CPU资源利用率

提升吞吐量

提升程序响应速度

更好的编程模型

2.并发带来的问题

1.安全性问题

  • 0.定义:什么是安全性问题

    • 多线程读写共享变量时出现不正确的结果

      • 共享变量
      • 多线程读&写
      • 不正确结果
  • 1.出现安全性问题的原因

    • 0.原子性问题

      • CPU时钟中断带来的线程切换
    • 1.可见性问题

      • 多核CPU高速缓存之间不可见
    • 2.重排序问题

      • CPU和编译器会进行重排序指令

        • 典型问题:单例模式DCL
  • 2.解决方案

    • 解决原子性问题

      • 0.前置知识

        • CPU硬件如何实现原子性

          • #LOCK信号总线锁

            • 原子指令:CMPXCHG/XADD/BTS
          • 缓存锁定(缓存一致性协议)

      • 1.CAS无锁算法

        • 底层使用CMPXCHG原子指令

        • CAS三大注意事项

          • ABA问题
          • 循坏开销大
          • 多变量问题
        • 实现方法

          • unsafe工具类
      • 2.通用互斥锁管程模型

        • 管程

          • 定义

            • 管理并发过程中的共享变量及其操作过程
          • MESA模型

            • 线程阻塞队列

            • 条件变量

            • 条件变量等待队列

            • 编程范式

              • while循坏检测

                • 虚假唤醒
                • 条件变更
        • sychronized

          • 对象头锁结构

          • 锁优化

            • 偏向锁

            • 轻量级锁

            • 重量级锁

              • 底层ObjectMonitor

                • _waitSet
                • _EntryList
                • _cxq
    • 解决可见性问题和重排序

      • Java内存模型(JMM)

        • 按需禁用缓存和编译优化(重排序)

          • volatile
          • final
        • Happens-Before规则

          • 要求前一个操作的结果对后一个操作可见
    • 并发包实现基石

      • volatile变量读写+CAS无锁算法
    • 并发同步工具和机制

      • 基于AQS的同步组件

      • 原子变量

        • AtomicLong
        • LongAdder
      • 等待通知机制

        • wait
        • notify/notifyAll
      • 线程封闭

        • ThreadLocal
      • 非阻塞同步机制

活跃性问题

  • 死锁

    • 定义

      • 一组相互竞争资源的线程因互相等待,导致”永久“阻塞的现象
    • 死锁的四大条件

      • 互斥

        • 共享资源只能被一个线程占用
      • 占有且等待

        • 已占有资源的线程,在等待其他资源时不释放原有资源
      • 不可抢占

        • 线程不能抢占其他线程已占有的资源
      • 循环等待

        • 出现线程之间相互等待对方资源的情况
    • 打破死锁

      • 打破“占有且等待”

        • 一次性申请所有资源
      • 打破“不可抢占”

        • 已占有资源的线程,如果申请不到其他资源,主动释放原有资源

          • 并发包的LOCK
      • 打破“循环等待”

        • 按统一顺序申请资源
  • 活锁

    • 没有阻塞但不满足条件无法继续执行

      • 等待随机时间
  • 饥饿

    • 长期获取不到资源无法继续执行

      • 公平分配

性能问题

  • Amdahl定律

      - 使用无锁算法和数据结构
    
      	- ThreadLocal
      	- 写时复制
      	- 乐观锁
    
      - 减小锁持有范围
    
      	- 细粒度锁
    
      		- 分段锁
      		- 读写锁
    
  • 上下文切换

    • 合理配置并发线程数
  • 伪共享

    • 原因

      • 最小单位缓存行
    • 解决方案

      • 变量填充
      • jdk8 @Contended
  • 衡量指标

    • 吞吐量
    • 延迟时间
    • 并发量

3.线程生命周期

通用状态

  • 初始状态

    • 编程语言特有,操作系统层还没有真正创建
  • 运行状态

    • 运行中
  • 可运行状态

    • 可分配CPU执行
  • 休眠状态

  • 终止状态

Java线程状态

  • NEW(初始化)

  • RUNNABLE(可运行状态/运行状态)

  • BLOCKED(阻塞状态)

    • synchronized
  • WAITING(无限时等待)

  • TIMED_WAITING(有限时等待)

    • sleep
    • wait()带超时参数
    • join()带超时参数
    • LockSupport.park()带超时参数
  • TERMINATED

4.并发工具类

Condition

AQS

  • 同步状态

    • state
  • 同步队列

    • CLH
  • 模板方法

    • 独占式获取和释放同步状态

      • 获取

        • void acquire(int args)

          • 独占式获取
        • void acquireInterruptibly(int args)

          • 可响应中断
        • boolean tryAcquireNanos(int args,long nanos)

          • 在响应中断的基础上加入了超时机制
      • 释放

        • release(int args)

          • 独占式释放
    • 共享式获取和释放同步状态

      • 获取

        • acquireShared(int args)

          • 共享式获取
        • acquireSharedInterruptibly(int args)

          • 可响应中断
        • tryAcquireSharedNanos(int args,long nanos)

          • 在响应中断的基础上加入了超时机制
      • 释放

        • releaseShared(int args)

          • 独占式释放
    • 查询同步队列线程集合

      • getQueuedThreads()
  • 重写方法

    • tryAcquire(int args)
    • tryRelease(int args)
    • tryAcquireShared(int args)
    • tryReleaseShared(int args)
    • isHeldExclusively

Lock

  • 和synchronized的区别

    • 响应中断
    • 支持超时
    • 非阻塞式获取锁

ReadWriteLock和StampedLock

  • ReadWriteLock

    • 读锁

      • 高16位表示读锁状态
    • 写锁

      • 低16位表示写锁状态
    • 锁不能升级,只能降级。升级会使写锁永久阻塞等待

    • 写锁支持条件变量,读锁是不支持条件变量的

  • StampedLock

    • 写锁
    • 悲观读锁
    • 乐观读
    • 加锁成功会返回stamp,解锁需要传入stamp
    • 性能更好
    • 不可重入
    • 不支持条件变量
    • 使用readLock() 或writeLock() 时,不能使用阻塞线程的interrupt(),需要使用可中断的悲观读锁 readLockInterruptibly() 和写锁 writeLockInterruptibly()

Semaphore

CountDownLatch

  • 解决一个线程等待多个线程的场景
  • 计数器是不能循环利用

CyclicBarrier

  • 一组线程之间互相等待
  • 计数器是可以循环利用,自动重置
  • 可以设置回调函数

并发容器类

  • List

    • CopyOnWriteArrayList
  • Map

    • ConcurrentHashMap
    • ConcurrentSkipListMap
  • Set

    • CopyOnWriteArraySet
    • ConcurrentSkipListSet
  • Queue

    • .单端阻塞队列

      • ArrayBlockingQueue
      • LinkedBlockingQueue
      • SynchronousQueue
      • LinkedTransferQueue
      • PriorityBlockingQueue
      • DelayQueue
    • 双端阻塞队列

      • LinkedBlockingDeque
    • 单端非阻塞队列

      • ConcurrentLinkedQueue
    • 双端非阻塞队列

      • ConcurrentLinkedDeque

原子类

  • 基本数据类型

    • AtomicBoolean
    • AtomicInteger
    • AtomicLong
  • 对象引用类型

    • AtomicReference
    • AtomicStampedReference
    • AtomicMarkableReference
  • 数组类型

    • AtomicIntegerArray
    • AtomicLongArray
    • AtomicReferenceArray
  • 对象属性更新器

    • AtomicIntegerFieldUpdater
    • AtomicLongFieldUpdater
    • AtomicReferenceFieldUpdater
  • 累加器

    • DoubleAccumulator
    • DoubleAdder
    • LongAccumulator
    • LongAdder

线程池

  • ThreadPoolExecutor
  • Executors
  • Future
  • FutureTask
  • CompletableFuture
  • CompletionService
  • Fork/Join

5.并发设计模式

Immutability模式

  • 基础类型包装类

Copy-on-Write模式

  • 基础类型包装类

线程本地存储模式

  • ThreadLocal

Guarded Suspension模式

  • 等待唤醒机制

Balking模式

Thread-Per-Message模式

  • 协程
  • Fiber

Worker Thread模式

  • Java线程池

两阶段终止模式

生产者-消费者模式

  • Java线程池
  • MQ

6.Java异步编程技术

显时使用线程

  • 实现Runnable接口
  • 继承Thread类

显时使用线程池

  • 实现方式

基于Future实现

  • FutureTask
  • CompletableFuture

基于反应式编程

  • 基于RxJava
  • 基于Reactor

异步的Web Servlet

Spring WebFlux

7.参考资料

JSR 133

Java并发编程网

《Java并发编程实战》

《Java并发编程的艺术》

《Java异步编程实战》

  • 7
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CodeMavs

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值