Java线程池

文章目录

  • 一、线程池的工作流程
  • 二、创建常见的线程池
  • 三、线程池中的参数

线程池的作用:相当于提前把线程创建好放入线程池中,后续需要用到线程时直接从线程池中取出线程,减少了创建新线程的开销,提高了程序的执行效率。

一、线程池的工作流程

线程池的工作流程分为三层。
第一层:判断线程池中核心线程的数目是否到达上限,是则进入下一层,否则创建新的核心线程开始执行任务。
第二层:判断线程池中阻塞队列的任务是否已满,是则进入下一层,否则将任务加入到阻塞队列中等待后续处理。
第三层:判断核心线程之外的线程数目数目是否达到上限,是则执行拒绝策略,否则创建核心线程之外的线程开始执行任务。

二、创建常见的线程池

代码示例如下:

ExecutorService service = Executors.newCachedThreadPool();

有多种创建线程池的工厂方法。
①Executors.newCachedThreadPool()构造出来的线程池的特点是线程数目是动态适应的,随着往线程池里添加任务,线程池中的线程会根据需要自动被创建出来。
②Executors.newFixedThreadPool(4)会指定线程池中创建线程的个数。
③Executors.newSingleThreadExecutor()是只有一个线程的线程池(这个工厂方法用得不多)。
④Executors.newScheduledThreadPool(1000)相当于定时器,但与定时器不同的是它不是一个扫描线程负责执行任务,而是多个线程执行任务。使用方式如下:

class Test1 {
    public static void main(String[] args) {
        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(10);//10代表线程池中核心线程数目corePoolSize
        for (int i = 0; i < 10; i++) {
            int id = i;
            scheduledExecutorService.schedule(new Runnable() {
                @Override
                public void run() {
                    System.out.print(id + " ");
                }
            }, 20, TimeUnit.SECONDS);//20秒后再开始执行任务,TimeUnit.SECONDS是秒的意思
        }
    }
}

ScheduledExecutorService类继承于ExecutorService类是ExecutorService类的子类,向scheduledExecutorService.schedule()的schedule()中传入任务。

三、线程池中的参数

Java标准库中有一个ThreadPoolExecutor类型,功能非常丰富,提供了很多参数,上诉①②③④这些工厂方法,其实是给ThreadPoolExecutor类填写了不同的参数然后用来构造线程池。
ThreadPoolExecutor类构造方法的参数有很多。
Java线程池_第1张图片
第一组参数int corePoolSize,int maximumPoolSize描述了线程池中线程的数目,int corePoolSize是核心线程数目;int maximumPoolSize是最大线程数目,线程池中线程的数目是可以动态变化的,变化的范围就是[corePoolSize, maximumPoolSize]。

第二组参数long keepAliveTime,TimeUnit unit。long keepAliveTime表示线程没有任务执行时最多保持多久时间会终止;TimeUnit unit是long keepAliveTime的单位,可以是ms,s,min…

第三个参数BlockingQueue workQueue是阻塞队列,用来存放线程池中的任务,可以根据需要灵活地设置这个队列的实现方式,需要优先级时可以使用PriorityBlockingQueue,如果不需要优先级并且任务数目是相对恒定时可以使用ArrayBlockingQueue,如果不需要优先级并且任务数目变动较大时可以使用LinkedBlockingQueue。

第四个参数ThreadFactory threadFactory是“工厂模式”的体现,使用ThreadFactory作为工厂类,由这个工厂类的工厂方法负责创建出线程。使用工厂类创建线程主要是为了在创建的过程中对线程的属性做出一些设置,手动创建线程时需要手动设置这些属性,而通过工厂类的工厂方法创建线程不仅可以把线程创建出来而且可以把线程属性设置好。

第五个参数RejectedExecutionHandler handler表示线程池的拒绝策略,一个线程池能容纳的任务数量有上限,一旦线程池中的任务数量达到了上限,如果继续往线程池中添加任务,不同的拒绝策略程序就会产生不同的效果。
下面有四个类,这四个类代表不同的四种拒绝策略,想使用哪种拒绝策略,就把哪个类创建出对象往ThreadPoolExecutor的第五个参数上传。
ThreadPoolExecutor.AbortPolicy:直接抛出异常。
ThreadPoolExecutor.CallerRunsPolicy:新添加的任务由添加任务的线程负责执行。
ThreadPoolExecutor.DiscardOldestPolicy:丢弃任务队列中最旧的任务。
ThreadPoolExecutor.DiscardPolicy:丢弃当前新添加的任务。

你可能感兴趣的:(java,开发语言,线程池)