线程池

[TOC]

线程池

一、两种类型线程池

  • ThreadPoolExecutor
  • ForkJoinPool
    • 分解汇总的任务
    • 用很少的线程可以执行很多的任务(子任务)TPE做不到先执行子任务
    • CPU密集型

二、ThreadPoolExecutor

线程池里面维护这两个集合

  • 线程的集合
  • 任务的集合

[图片上传失败...(image-b96de3-1639467255135)]

线程池有哪些配置

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler)
  • corePoolSize:核心线程数
  • maximumPoolSize:线程池最大线程数,表示在线程池中最多能创建多少个线程。如果当线程池中的数量到达这个数字时,新来的任务会抛出异常。
  • keepAliveTime:生存时间
  • unit:生存时间单位
  • workQueue:任务队列
  • threadFactory:线程工厂,主要用来创建线程,比如指定线程的名字,是否是守护线程,优先级等等
  • RejectedExecutionHandler:拒绝策略,任务队列满,线程池超过最大线程数,然后就是执行拒绝策略,jdk默认提供4中,这个可以自定义,Abort:抛异常;Discard:扔掉,不抛异常;DiscardOldest:扔掉排队时间最久的;CallerRuns:调用者处理任务

三、Executors -线程池的工厂

1、newSingleThreadExecutor

new ThreadPoolExecutor(1, 1,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue()))

为什么要有单线程的线程池

1、创建线程需要耗费资源,2、生命周期管理 3、任务队列

2、newCachedThreadPool

public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue());
}

SynchronousQueue 也是一个队列来的,但它的特别之处在于它内部没有容器,一个生产线程,当它生产产品(即put的时候),如果当前没有人想要消费产品(即当前没有线程执行take),此生产线程必须阻塞,等待一个消费线程调用take操作,take操作将会唤醒该生产线程,同时消费线程会获取生产线程的产品(即数据传递),这样的一个过程称为一次配对过程(当然也可以先take后put,原理是一样的)。

不建议使用

3、newFixedThreadPool-固定的

public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue());
}

4、newScheduledThreadPool-定时任务线程池

 public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
        return new ScheduledThreadPoolExecutor(corePoolSize);
    }
public ScheduledThreadPoolExecutor(int corePoolSize) {
        super(corePoolSize, Integer.MAX_VALUE,
              DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS,
              new DelayedWorkQueue());
    }

定时器框架 quartz cron

面试:假如提供一个闹钟服务,订阅这个服务的人特别多,10亿人,怎么优化?

并发:任务提交

并行:任务执行

并行是并发子集

5、workstealingThread

workstealingThread原理

好处:把大任务切分成一个一个小任务

5、newCachedThreadPool VS newFixedThreadPool

[图片上传失败...(image-e8bd-1639467255135)]

阿里都不用,自己估算,进行精确的定义

你可能感兴趣的:(线程池)