Java——线程池

线程池构造:

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
        //忽略赋值与校验逻辑
    }

构造参数:

  • corePoolSize线程池中的核心线程数
  • maximumPoolSize线程池中的最大线程数
  • keepAliveTime线程池中的线程存活时间(准确来说应该是没有任务执行时的回收时间,后面会分析)
  • unit时间单位
  • workQueue来不及执行的任务存放的阻塞队列
  • threadFactory新建woker线程(注意不是我们提交的任务)是进行一些属性设置,比如线程名,优先级等等,有默认实现。
  • handler 任务拒绝策略,当运行线程数已达到maximumPoolSize,队列也已经装满时会调用该参数拒绝任务,有默认实现。

 

线程池策略:

1、当线程池中的线程数小于corePoolSize 时,新提交的任务直接新建一个线程执行任务(不管是否有空闲线程) 
2、当线程池中的线程数等于corePoolSize 时,新提交的任务将会进入阻塞队列(workQueue)中,等待线程的调度 
3、当阻塞队列满了以后,如果corePoolSize < maximumPoolSize ,则新提交的任务会新建线程执行任务,直至线程数达到       maximumPoolSize 
4、当线程数达到maximumPoolSize 时,新提交的任务会由(饱和策略)管理

Java提供封装好的线程池方法:

        Executors.newCachedThreadPool();
        Executors.newFixedThreadPool(3);
        Executors.newSingleThreadExecutor();
        Executors.newScheduledThreadPool(3);

Fixed 固定线程的线程池,超过固定数就会进入任务队列。任务队列默认值Integer.Max_VALUE

Cached 缓冲线程池,当任务完成并且当前线程数超过corePoolSize的时候会在timeOut时间后回收非核心线程。

Single 单线程线程池,提交的任务在队列里,按照FIFO的顺序依次执行提交的任务,当有需求几个任务只想顺序有先后要求的时候,可以使用此线程池。

Scheduled 可执行定时任务的线程池。

 

任务队列的三种策略:

  • 直接提交。工作队列的默认选项是SynchronousQueue,它将任务直接提交给线程而不保持它们。在此,如果不存在可用于立即运行任务的线程,则试图把任务加入队列将失败,因此会构造一个新的线程。此策略可以避免在处理可能具有内部依赖性的请求集时出现锁。直接提交通常要求无界maximumPoolSizes 以避免拒绝新提交的任务。当命令以超过队列所能处理的平均数连续到达时,此策略允许无界线程具有增长的可能性。
  • 无界队列。使用无界队列(例如,不具有预定义容量的 LinkedBlockingQueue)将导致在所有 corePoolSize线程都忙时新任务在队列中等待。这样,创建的线程就不会超过 corePoolSize。(因此,maximumPoolSize的值也就无效了。)当每个任务完全独立于其他任务,即任务执行互不影响时,适合于使用无界队列;例如,在 Web页服务器中。这种排队可用于处理瞬态突发请求,当命令以超过队列所能处理的平均数连续到达时,此策略允许无界线程具有增长的可能性。
  • 有界队列。当使用有限的 maximumPoolSizes 时,有界队列(如ArrayBlockingQueue)有助于防止资源耗尽,但是可能较难调整和控制。队列大小和最大池大小可能需要相互折衷:使用大型队列和小型池可以最大限度地降低CPU 使用率、操作系统资源和上下文切换开销,但是可能导致人工降低吞吐量。如果任务频繁阻塞(例如,如果它们是 I/O边界),则系统可能为超过您许可的更多线程安排时间。使用小型队列通常要求较大的池大小,CPU使用率较高,但是可能遇到不可接受的调度开销,这样也会降低吞吐量。

感谢以下博客作为参考:

https://blog.csdn.net/hayre/article/details/53291712

https://www.jianshu.com/p/5df6e38e4362

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值