• 并发与多线程


    知识点汇总

    一、死锁

    1.1 竞争条件与临界区

    1.2 死锁检测与防止

    1.3 产生条件
      互斥
      请求并持有
      非剥夺
      循环等待

    二、线程的状态与转换

    NEW:创建

    RUNNABLE:可运行

    REDAY:就绪态

    RUNNING:运行态

    BLOCKED:获取锁失败进入BLOCKED状态,获取锁时进入REDAY态

    TIME_WAITING:超时等待

    WAITING:无超时等待

    TERMINATED:结束

     掌握5种状态即可(新建、就绪、运行、阻塞、死亡)

    三、线程同步与互斥解决方法

      1、CAS
      2、synchronize
      3、lock

    3.1 CAS

      CAS是乐观锁,轻量级锁,通过比较值是否被更改来判断。

      缺点:可能会出现的ABA(上图右)的问题,不一定会影响结果,解决办法是提供额外的标志位或者时间戳(类似于mysql version字段)。

    3.2 synchronize

      方法同步:通过java的高级字节码指令ACC_SYNCCHRONIZED标志来实现。

      代码块同步:通过java的两个高级字节码指令monitorenter和monitorexit来实现。

      锁优化机制:

      1、偏向锁:先使用偏向锁
      2、轻量锁:获取偏向锁失败则升级为CAS轻量锁
      3、自旋锁:获取轻量锁失败,则进行短暂的自旋
      4、重量级锁:以上都失败则升级为重量级锁

    3.3 AQS和LOCK

     lock锁代码块,类似与cas

    四、线程池

      1、固定大小线程池:线程池固定,使用的是无界缓冲队列,适用于任务数量不均匀的场景,也适用于对内存压力不敏感,对系统负载比较敏感的场景。

      2、Cached线程池:不限制创建的线程数,适用于要求低延迟的短期任务的场景。

      3、单线程线程池:一个线程的固定线程池,适用于需要异步执行,但要保证线程执行顺序的场景。

      4、Scheduled线程池:适用于定期执行任务的场景,支持按固定的频率或者固定延时来执行的场景。

      5、工作窃取线程池:适用于任务时长不均匀的场景。

    4.1 线程池参数介绍

    参数介绍:
      corePoolSize:核心线程数,核心线程会一直存活。
      maximumPoolSize:最大线程数,决定线程池最多可以创建多少线程。
      keepAliveTime:空闲时间,当线程闲置超过空闲时间时就会被销毁。
      uint:空闲时间的单位。
      workQueue:缓冲队列
      ArrayBlockingQueue:有界队列,有最大容量闲置。
      LinkedBlockingQueue:无界队列,不限制容量。
      SynchronousQueue:同步队列,内部没有缓冲区。
      threadFactory:设置线程池工厂方法,用来创建新的线程方法,可以对线程的属性进行定制,例如线程的group,线程名等,一般使用默认的工厂类即可。
      handler:线程池满时的拒绝策略,
      Abort:线程池满后,提交新任务时,会抛出异常,默认拒绝策略。
      Discard:线程池满后,提交新任务时,对任务进行丢弃。
      CallerRuns:线程池满后,提交新任务时,会直接执行提交的任务。
      DiscardOldest:线程池满后,提交新任务时,会丢弃最早提交的任务。
    各类线程池调用参数方法:
      固定大小线程池:
        corePoolSize和maximumPoolSize:设置成指定的线程数
        workQueue:LinkedBlockingQueue
      Cached线程池:
        corePoolSize:0
        maximumPoolSize:Integer.MAX_VALUE
        keepAliveTime:60
        workQueue:SynchronousQueue
      单线程线程池:
        corePoolSize和maximumPoolSize:1
      Scheduled线程池:
        workQueue:DelayWorkQueue,按延迟时间获取任务的优先级队列

    4.2 线程池任务执行流程

    调用方法:
      1、execute
      2、submit:可以返回一个future对象,根据future对象可以了解任务的执行情况,可以取消任务的执行,还可以获取任务的执行结果或者执行异常。

    五、JUC常用工具

    用于处理多线程常见问题的库

    表格第一行:基本数据类型的原子类。

    表格第二行:对对象提供的原子类。

     

    表格第一行:锁相关的类。

    表格第二行:异步执行相关的类。

     

    表格第一行:常用的阻塞队列。

    表格第二行:控制多线程协作使用的类。

    表格第三行:常用的并发集合。

    面试考察点与真题

    3、jstack分析线程的运行状态

     

    4、wait与sleeep的区别

      wait:Object方法,会释放对象锁,需要在同步块中使用,不需要捕获异常。
      sleep:Thread方法,不会释放对象锁,任何地方使用,需要捕获异常。
    6、适用于读并发多,写并发少的场景,也可使用CopyOnWrite解决。

    7、wait、notify机制,共享变量的sync和lock同步机制

    8、cas、sync、lock、ThreadLocal等机制

    9、减少临界区范围、使用ThreadLocal、减少线程切换、使用读写锁或CopyOnWrite等机制

    10、ThreadLocal不是解决线程数据共享的问题,是解决数据隔离的问题。

  • 相关阅读:
    CStdioFile的Writestring无法写入中文的问题
    Warning: skipping non-radio button in group. 的处理
    Linux命令 改变文档权限及所有者
    动态链接库dll的 静态加载 与 动态加载
    switch的方便用法
    mysql 安装过程中的错误:my-template.ini could not be processed and written to XXXmy.ini.Error code-1
    HDU 3790 最短路径问题 (SPFA)
    container_of用法及实现
    ZXing工具类v1.0
    基于MapReduce的HBase开发
  • 原文地址:https://www.cnblogs.com/zeussbook/p/11801435.html
Copyright © 2020-2023  润新知