线程池

作者: 蒸汽飞船 | 来源:发表于2018-07-10 23:30 被阅读25次

并行:多核cpu同时处理多件事
并发:伪并行

继承关系:ThreadPoolExecutor->ExecutorService->Executor
Executors:ThreadPoolExecutor的工厂类,生成不同的线程池

线程池:接口:ExecutorService->实现类ThreadPoolExecutor
1:int corePoolSize (core:核心的) = > 该线程池中核心线程数最大值
什么是核心线程:线程池新建线程的时候,如果当前线程总数小于 corePoolSize ,则新建的是核心线程;如果超过corePoolSize,则新建的是非核心线程。

默认情况下核心线程会一直存活在线程池中,即使这个核心线程啥也不干(闲置状态)。
如果指定ThreadPoolExecutorallowCoreThreadTimeOut这个属性为true,那么核心线程如果不干活(闲置状态)的话,超过一定时间( keepAliveTime),就会被销毁

2:int maximumPoolSize = > 该线程池中线程总数的最大值
线程总数计算公式 = 核心线程数 + 非核心线程数。

3:long keepAliveTime = > 该线程池中非核心线程闲置超时时长
注意:一个非核心线程,如果不干活(闲置状态)的时长,超过这个参数所设定的时长,就会被销毁掉。但是,如果设置了allowCoreThreadTimeOut = true,则会作用于核心线程。

4:TimeUnit unit = > (时间单位)
5:BlockingQueue<Runnable> workQueue = >( Blocking:阻塞的,queue:队列)

workQueue类型:
一般来说,workQueue有以下四种队列类型:

SynchronousQueue:(同步队列)->搭配不限制线程数量

这个队列接收到任务的时候,会直接提交给线程处理,而不保留它(名字定义为 同步队列)。但有一种情况,假设所有线程都在工作怎么办?

这种情况下,SynchronousQueue就会新建一个线程来处理这个任务。所以为了保证不出现(线程数达到了maximumPoolSize而不能新建线程)的错误,使用这个类型队列的时候,maximumPoolSize一般指定成Integer.MAX_VALUE,即无限大,去规避这个使用风险。

LinkedBlockingQueue(链表阻塞队列):长度无限的话->线程数不回超过核心线程

当然也可以限定长度,采用队列实现所以说写个100万的长度也没事
这个队列接收到任务的时候,如果当前线程数小于核心线程数,则新建线程(核心线程)处理任务;如果当前线程数等于核心线程数,则进入队列等待。由于这个队列没有最大值限制,即所有超过核心线程数的任务都将被添加到队列中,这也就导致了maximumPoolSize的设定失效,因为总线程数永远不会超过corePoolSize

ArrayBlockingQueue(数组阻塞队列):固定长度->超过总线程数报错

可以限定队列的长度(既然是数组,那么就限定了大小),接收到任务的时候,如果没有达到corePoolSize的值,则新建线程(核心线程)执行任务,如果达到了,则入队等候,如果队列已满,则新建线程(非核心线程)执行任务,又如果总线程数到了maximumPoolSize,并且队列也满了,则发生错误

DelayQueue(延迟队列):

队列内元素必须实现Delayed接口,这就意味着你传进去的任务必须先实现Delayed接口。这个队列接收到任务时,首先先入队,只有达到了指定的延时时间,才会执行任务

处理逻辑:
1:如果线程数量未达到corePoolSize,则新建一个线程(核心线程)执行任务
2:如果线程数量达到了corePools,则将任务移入队列等待
3:如果队列已满,新建线程(非核心线程)执行任务
4:如果队列已满,总线程数又达到了maximumPoolSize,就会由RejectedExecutionHandler抛出异常

四种常用的线程池:
1.newFixedThreadPool 固定线程数,队列无限长,超时时间为0

2.newCachedThreadPool:核心线程0,最大线程无限,超时60秒,单一队列

3.newSingleThreadExecutor:只有一个核心线程,队列无限长,超时0

4.newScheduledThreadPool:循环或者延迟任务

ScheduledExecutorService:延时+循环
参考

public interface ScheduledExecutorService extends ExecutorService {
  //延时调用
    public ScheduledFuture<?> schedule(Runnable command,
                                           long delay, TimeUnit unit);

    public <V> ScheduledFuture<V> schedule(Callable<V> callable,
                                           long delay, TimeUnit unit);

    //循环+延时执行:每隔period时间提交一个任务,不关心任务执行时长
    public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
              long initialDelay,
              long period,
              TimeUnit unit);
    //循环+延时执行:每个任务执行完,再间隔delay再提交任务
    public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,
                                             long initialDelay,
                                             long delay,
                                             TimeUnit unit);
}

相关文章

  • java线程池

    线程VS线程池 普通线程使用 创建线程池 执行任务 执行完毕,释放线程对象 线程池 创建线程池 拿线程池线程去执行...

  • java----线程池

    什么是线程池 为什么要使用线程池 线程池的处理逻辑 如何使用线程池 如何合理配置线程池的大小 结语 什么是线程池 ...

  • Java线程池的使用

    线程类型: 固定线程 cached线程 定时线程 固定线程池使用 cache线程池使用 定时调度线程池使用

  • Spring Boot之ThreadPoolTaskExecut

    初始化线程池 corePoolSize 线程池维护线程的最少数量keepAliveSeconds 线程池维护线程...

  • 线程池

    1.线程池简介 1.1 线程池的概念 线程池就是首先创建一些线程,它们的集合称为线程池。使用线程池可以很好地提高性...

  • 多线程juc线程池

    java_basic juc线程池 创建线程池 handler是线程池拒绝策略 排队策略 线程池状态 RUNNIN...

  • ThreadPoolExecutor线程池原理以及源码分析

    线程池流程: 线程池核心类:ThreadPoolExecutor:普通的线程池ScheduledThreadPoo...

  • 线程池

    线程池 [TOC] 线程池概述 什么是线程池 为什么使用线程池 线程池的优势第一:降低资源消耗。通过重复利用已创建...

  • java 线程池使用和详解

    线程池的使用 构造方法 corePoolSize:线程池维护线程的最少数量 maximumPoolSize:线程池...

  • 线程池

    JDK线程池 为什么要用线程池 线程池为什么这么设计 线程池原理 核心线程是否能被回收 如何回收空闲线程 Tomc...

网友评论

      本文标题:线程池

      本文链接:https://www.haomeiwen.com/subject/slweeftx.html