关于java:java线程池追问集

55次阅读

共计 1907 个字符,预计需要花费 5 分钟才能阅读完成。

1. 线程池的作用

  • 升高资源耗费:通过重用曾经创立的线程来升高线程创立和销毁的耗费
  • 进步响应速度:工作达到时不须要期待线程创立就能够立刻执行
  • 进步线程的可管理性:线程池能够对立治理、调配、调优和监控

2. 线程池的组成

  • 线程池管理器(ThreadPool):用于创立并治理线程池,包含 创立线程池,销毁线程池,增加新工作;
  • 2、工作线程(PoolWorker):线程池中线程,在没有工作时处于期待状态,能够循环的执行工作;
  • 3、工作(Task):实现某个事件,它次要规定了工作的入口,工作执行完后的收尾工作,工作的执行状态等;
  • 4、工作队列(taskQueue):用于寄存没有解决的工作。提供一种缓冲机制。

3. 线程池的应用逻辑

4. 罕用线程池的品种

  • Java 通过 Executors 提供了四种线程池,这四种线程池都是 间接或间接 配置 ThreadPoolExecutor 的参数实现的。

    • newCachedThreadPool:用来创立一个能够有限扩充的线程池,实用于负载较轻的场景,执行短期异步工作。(能够使得工作疾速失去执行,因为工作工夫执行短,能够很快完结,也不会造成 cpu 适度切换)

    SynchronousQueue:一个不存储元素的阻塞队列。每个插入操作必须等到另一个线程调用移除操作,否则插入操作始终处于阻塞状态,吞吐量通常要高于 LinkedBlockingQueue。

    • 该线程池的工作机制是:
      1. 没有外围线程,间接向 SynchronousQueue 中提交工作
        1. 如果有闲暇线程,就去取出工作执行;如果没有闲暇线程,就新建一个
        1. 执行完工作的线程有 60 秒生存工夫,如果在这个工夫内能够接到新工作,就能够持续活下去,否则就拜拜
    • newFixedThreadPool:创立一个固定大小的线程池,因为采纳无界的阻塞队列,所以理论线程数量永远不会变动,实用于负载较重的场景,对以后线程数量进行限度。(保障线程数可控,不会造成线程过多,导致系统负载更为严重)
    • newSingleThreadExecutor:创立一个单线程的线程池,实用于须要保障程序执行各个工作。
    • newScheduledThreadPool:实用于执行延时或者周期性工作。

    4.1 ScheduledThreadPoolExecutor 增加工作提供了另外两个办法:

    scheduleAtFixedRate():按某种速率周期执行
    scheduleWithFixedDelay():在某个提早后执行

    • 该线程池的工作机制是:

        1. 调用下面两个办法增加一个工作
        1. 线程池中的线程从 DelayQueue 中取工作(time 大于等于以后工夫的)
        1. 而后执行工作
        1. 执行完的工作批改 time 到指定工夫,重新加入队列

– 5. 线程池的参数

  • corePoolSize:线程池中的外围线程数

    • 外围线程会始终存活,即便是闲置状态
    • CPU 密集型的工作(加密、解密、压缩、简单计算),个别 core 设置为 CPU 核数 + 1, 避免频繁的上下文切换;
    • IO 密集型的工作(读写数据库、网络申请、文件读写),个别 core 设置为 CPU 核数 * 2
    • 具体要设置多少,还是测试、生产环境须要重复调试、批改
  • maximumPoolSize:线程池中最大线程数

    • 个别生产环境和 core 配的统一,避免线程池震荡
  • keepAliveTime:闲置超时工夫

    • poolSize > corePoolSize 后创立的为闲置线程 – 如果服务波峰之后有较长时间的波谷,能够思考尽快超时回收;如果是密集的波峰,就要配久一点再超时
  • unit:keepAliveTime 超时工夫的单位(时 / 分 / 秒等)
  • workQueue:线程池中的工作队列
  • threadFactory:为线程池提供创立新线程的线程工厂
  • rejectedExecutionHandler:线程池工作队列超过最大值之后的回绝策略

    • java 默认有 4 种实现, 如果不指定,默认抉择 Abort,上面排列由最消极到最踊跃 – DiscardPolicy, 抛弃工作,然而不抛出异样

      • DiscardOldestPolicy 抛弃队列最后面的工作,而后提交以后 Task 到队列尾部

        • AbortPolicy, 抛弃工作并抛出 RejectedExecutionException
      • CallerRunsPolicy 由调用线程解决该工作

– 6. 为什么要应用阻塞队列

  • 避免线程无限度的创立、节约内存导致 OOM or 节约 CPU 频繁进行上下文切换
  • 阻塞队列能够保障工作队列中没有工作时阻塞获取工作的线程,使得线程进入 wait 状态,开释 cpu 资源。
  • 当队列中有工作时才唤醒对应线程从队列中取出音讯进行执行。

参考:《2020 最新 Java 根底精讲视频教程和学习路线!》
链接:https://juejin.cn/post/693865…

正文完
 0