高并发编程、线程、锁(内置锁、显示锁)、CAS

Java 高并发核心编程(尼恩编著) 阅读提纲


  • 进程与线程

    • 进程: 系统并发调度的最小单位
    • 线程: CPU调度的最小单位、相当于进程代码段的一次顺序执行、调度效率高于进程调度
    • 进程与线程的区别
      • 线程是进程代码段的一次顺序执行、一个进程最少拥有一个线程
      • 进程是 系统调度的最小单位、线程是CPU调度的最小单位
      • 线程 是 基于高并发衍生出来的、充分发挥CPU性能、弥补进程却换过于笨重的问题
      • 切换速度不同、线程切换速度高于进程
      • 进程之间是相互独立的、线程之间不相互独立、方法去、堆内存、系统资源是共享的
  • 线程

    • 创建方式

      • Thread (继承)
      • Runable (实现)
      • Callable (实现、具有返回值)
      • FutureTask (同步阻塞获取返回值)
      • ThreadPool
        • Executes
          • 创建线程的方法
            • 单线程池 newSingleThreadPool
              • 特点: 只有一个线程工作、保证任务顺序执行
              • 缺点: 阻塞队列 为 LinkedBlockingQueue 无界阻塞队列、处理速度小于 任务新增的速度、会导致队列过大、容易造成 OOM 异常
            • 固定线程池 newFixedThreadPool
              • 特点: 新线程没有达到固定线程、新任务进来就会创建线程去执行、否则加入阻塞队列、任务结束回收线程
              • 缺陷: 阻塞队列 为 LinkedBlockingQueue 无界阻塞队列、处理速度小于 任务新增的速度、会导致队列过大、容易造成 OOM 异常
            • 调度线程池 newScheduleThreadPool
              • 特点: 延时、周期性的调度线程
              • 缺陷: 阻塞队列为delayedWorkQueue 、线程不设上限、如果大量任务到期、会导致大量线程被创建、CPU 线程资源耗尽
            • 可缓存线程池 newCacheThreadPool
              • 特点: 新任务进来会一直创建线程、直到达到JVM 或者系统最大线程、任务长时间不执行就会被回收
              • 缺陷: 一致创建线程、会导致大量线程被创建、容易导致OOM、严重会导致 CPU线程资源被耗尽、阻塞队列为 synchronousQueue 同步队列
        • ThreadPool
          • 创建方式 newThreadPoolExecutor(coreSize,maxSize,keepAliveTime,timeUtil,blockQueue,threadFactory,rejectHandler)
          • 参数详解
            • coreSize 核心线程数大小(新任务进来、已创建线程没超过核心最大线程数、会优先创建线程、不论已有线程是否有正在执行的任务)
            • maxSize 最大线程数 (核心线程数已满且不处于空闲状态、阻塞队列已满、就会创建线程、工作线程不能大于最大线程)
            • keepAlive   线程存活时间、非核心线程、空闲时间超过最大存活时间就会被回收
            • timeUtil 存活单位
            •  blockQueue 阻塞队列 存放异步线程、核心线程已满、无空闲线程、新任务进来就会被存入阻塞队列
              • ArrayBlockQueue 有界队列  FIFO
              • LinkedBlockQueue 不设置大小为无界队列、FIFO
              • PriorityBlockQueue 优先级队列 
              • DelayQueue 延时队列、超过期限出列
              • SynchronousQueue 同步队列、不存储元素、插入操作 必须等待另一个元素的移除操作
            • threadFactory 线程工厂、维护线程的信息
            • rejectHandler 拒绝策略
              • abrot 线程池已满就抛出异常
              • discard 抛弃策略: 不会抛出异常
              • discardOld 抛弃最老任务策略: 队列已满就会抛弃最老任务、一般是队头
              • CallerRuns 调用者执行策略 : 队列已满、用调用者线程执行本次任务
              • 自定义策略
          • 调用流程
            • 新任务进来如果工作线程小于核心线程、创建新线程执行任务、不论核心线程(工作线程)是否有空闲、核心线程已满且无空闲工作线程、加入阻塞队列、如果核心线程已满、阻塞线程已满、再次创建线程执行、线程数不能大于最大线程数、超过最大线程数、走拒绝策略
          • 钩子方法
            • beforeExe 异步任务执行前执行
            • afterExe 异步任务执行后执行
            • terminated 线程中断执行
    • 生命周期

      • new 新建
      • runabel 就绪
      • running 运行 
      • block 阻塞
      • waiting 限时等待
      • destory 销毁
    • threadLocal

      • 定义: 共享变量都有一个线程自己独有的本地值
      • 使用场景: 
        • 线程隔离
        • 跨函数参数传递
      • 结构 Map
        • key : threadLocal
        • value : 本地私有值
    • 线程之间通信

      • wait
        • JVM 将 线程加入 锁对象监视器的 等待集 (waitSet)、等待其他线程唤起
        • 放弃锁对象的 owner 权限、其他线程可以抢夺监视器 权限
        • 线程状态更新为 waiting
      • notify
        • JVM 将 waitSet中第一个对象(notifyAll 是所有对象)移到 entryList中
        • 将线程状态由 waiting 改为 blocking,具备监视器的抢夺权限
        • 抢夺成功后、线程状态由 blocking 改为 runnable 具备重新执行的资格


内置锁

  • i++ 线程安全问题

    • 步骤: 内存取值、寄存器元素、内存赋值
    • 多个操作、可能存在先读后写的操作、取到的值无法保证是内存的值、导致值不一致
  • synchronized

    • 锁类型
      • 实例对象锁
      • 类锁(static)
    • 锁状态
      • 无锁
        • 对象头标记: 偏向锁 0,锁状态 01
      • 偏向锁
        • 对象头标记: 偏向锁 1, 锁状态 01
        • 解决问题: 无竞争状态下锁竞争问题(没有其他线程抢锁)
        • 原理: 不存在锁竞争的一个线程获取到了锁、锁就进入了偏向锁状态、记录线程ID、对象锁改为01,偏向改为1
        • 偏向锁撤销
          • 在一个安全点停止线程
          • 修复锁记录指向 mark word 、 清除线程id
          • 将当前锁升级为轻量级锁
          • 唤醒当前线程
        • 偏向锁升级(膨胀)
          • 一旦有第二线程去抢占这个锁、看到锁状态为偏向锁状态、JVM检查原来占有线程是否存活、挂了就将状态改为无锁状态、然后进行重新偏向、偏向为抢锁线程
          • 存活、进一步检查占有线程的栈信息是否通过锁记录持有偏向锁、存在记录、就表明 线程还在使用偏向锁、发生锁竞争、撤销偏向锁、将偏向锁升级为轻量级锁
      • 轻量级锁
        • 对象头标记: 锁状态 00
        • 抢锁行为: 当锁为偏向锁、另一个线程试图抢占、锁升级为轻量级锁、抢锁线程进行自旋
        • 自旋优化: 适应性自旋
      • 重量级锁
        • 对象头标记: 10
        • 锁升级条件: 
          • 超过最大等待时间还没有获取到锁、线程进入等待、该锁膨胀为重量级锁、指向监视器对象、登记 和 管理排队线程
        • 监视器
          • 属性
            • Cxq 
              • 所有请求锁线程先进入这个队列
              • 原理: 抢锁线程通过 CAS 自旋获取不到锁就会进入 cxq
            • entryList
              • cxq中 拥有 候选资源的线程会被加入 entryList
            • waitSet
              • 阻塞wait 方法 加入 waitSet,等待notify 唤醒、加入 entryList
            • owner : 指向获取锁线程

  • 17
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值