Java-并发

181 阅读4分钟

记录

日期说明
2023/1/1首次创建

总纲

总结关于并发的一些概念

生命周期

  • 状态:共5种。分别是创建、就绪、运行、阻塞、死亡
  • 优先级:1-10(最高),默认分配是5

线程池

参数

  • corePoolSize: 最大核心线程数
  • maximumPoolSize: 最大线程数
  • keepAliveTime: 非核心线程的空闲存活时间
  • unit: 线程空闲存活时间单位
  • workQueue: 存放任务的阻塞队列
  • threadFactory: 创建线程的工厂
  • handler: 线程池的饱和策略
    • abortPolicy: 抛出异常,默认
    • discardPolicy: 丢弃任务
    • discardOldestPolicy: 丢弃最老的任务,提交这个任务
    • callerRunsPolicy: 交给线程池调用所在的线程进行处理

execute流程

  1. 提交任务
  2. 如果核心线程数小于corePoolSize,创建核心线程去处理任务
  3. 否则放到任务队列workQueue
  4. 如果任务队列已满,判断线程数量是否达到maximumPoolSIze,如果没有就创建非核心线程处理任务
  5. 如果线程数已经达到最大,还有新任务就执行饱和策略

异常处理

  • try-catch捕获线程异常
  • 在自定义的线程工厂中,为工作线程设置UncaughtExceotionHandler,在uncaughtException方法中处理异常
  • 重写ThreadPoolExecutor的afterExecute方法,处理传递的异常引用
  • Future.get()可以捕获异常

submit流程

  • 构造Future对象
    • newTaskFor()
    • newFutureTask()
    • Executors.callable()
  • execute执行
    • addWroker()
    • runWorker()
  • 运行过程
    • run()
    • setException
      • Future.get()可以捕获异常

工作队列

  • ArrayBlockingQueue:
    • 数组实现的有界阻塞队列
    • FIFO
  • LinkedBlockingQueue:
    • 可设置容量的链表阻塞队列,最大Integer.MAX_VALUE
    • FIFO
    • newFixedThreadPool使用这个
    • 吞吐量高于ArrayBlockingQueue
  • DelayQueue:
    • 任务定时周期的延迟执行队列
    • 根据指定执行时间从小到大排列,否则根据先后排列
    • newSchedledThreadPool使用这个
  • PriorityBlockingQueue:
    • 具有优先级的无界阻塞队列
    • 不存储元素的阻塞队列。
    • 每个插入必须等另一个线程调用移除,否则就一直阻塞
    • newCachedThreadPool使用这个
    • 吞吐量高于LinkedBlockingQueue
  • SynchronousQueue:

常用线程池

  • newFixedThreadPool: 固定数量
  • newCachedThreadPool: 可缓存线程
  • newSingleTHreadExecutor: 单线程
  • new ScheduledThreadPool: 定时及周期执行

参考

实现方法

  1. 实现Runnable接口:更灵活,避免单继承的局限?适合多线程处理同一资源。多个Thread执行一个Runnable对象,有可能线程不安全。
  2. 继承Thread类:范文当前线程更简单,可以增强类的行为?。每个Thread唯一对应一个没人的Runnable对象。受到单继承的限制。
  3. 实现Callable接口,并结合Future使用:Callable可以有返回值,可以抛出异常

死锁

  • 线程安全:多线程在操作同一资源时能够安全的完全
  • 死锁条件:互斥、循环等待、不可抢占、请求与保持
  • 使用Semaphore.tryAcquire尝试加锁以避免死锁

重点概念

  1. 原则:原子性,可见性,有序性
  2. Java内存模型:变量存于主存,每个线程都有自己的工作内容?

关键字

  • volatile

    • 可见性:一个线程修改了某个变量的值,新值对其他线程是立即可见的
    • 有序性:禁止进行指令重排列
    • 使用:
      • 变量的写操作不依赖于当前值
      • 变量没有包含在具有其他变量的不变式中?
  • synchronized

    • 对象锁:锁住实例对象,线程1获取了对象a的对象锁,其他线程就不能进入需要获的对象实例a的对象锁才能访问的同步代码(包括同步方法和同步块)
      • this:
      • 非this:
      • 非静态方法
    • 类锁:锁住类,由于类的静态方法和变量(?)只有一份,一旦被锁住了,其他实例对象想要调用此方法就只能等待。类锁实质上是class对象的锁
      • 静态方法
      • 类class

中断

  • 中断是一种协作机制,不能直接终止另一个线程,而需要被中断的线程自己处理中断
  • 方法:interrupted(测试并消除中断状态),isInterrupt(测试),interrupt(中断)

线程隔断

  • 当线程较慢或阻塞时,有大量的请求造成线程数量剧增导致发生雪崩
  • 解决方法
    • 线程池:Hystrix(?),每个类型的业务生成一个线程池。
      • 优点:隔离增加了抗风险的能力,对于美俄个服务有了更便捷的调节和控制。
      • 缺点:增加了额外的开销,比如调度,维护等。

其他概念

  • 原子类:java.util.concurrent.atomic.*
  • 线程锁?
  • 信号量:用于控制并发数
  • countDawnLatch:用于异步执行多个任务,主线程等到任务都执行完毕?
  • BlockingQueue:putofferaddpolltake
  • 定时器ScheduleThreadPoolExcutor?
  • 合并分支框架ForkJoinTask?