美文网首页
java多线程-线程池

java多线程-线程池

作者: 探索者_逗你玩儿 | 来源:发表于2019-02-28 23:48 被阅读0次

java中不可避免的就是使用线程池TheadPoolExecutors,其中线程池的创建有两种方式:一种偷懒的做法就是通过Executors帮助类来简化线程池的创建

Executors.newFixedThreadPool
Executors.newFixedThreadPool
Executors.newSingleThreadExecutor
Executors.newCachedThreadPool
Executors.newScheduledThreadPool
Executors.newSingleThreadScheduledExecutor

另外一种是通过TheadPoolExecutor 来创建。虽说明面上创建方式是两种,但是底层实现就是一套,第一套创建方式是在第二套的基础上进一步封装而来的,既然明白了其中的关系,那么我们就直接跳过第一种方式,直接来看第二种实现方式,弄懂了第二种方式,第一种方式就水到渠成了。

首先我们来看看TheadPoolExecutor的类图,看懂这张图对于我们后面理解线程池有很大的帮助 diagram.png
通过类图可以看到线程池有两种提交任务的方式,一个是在Executor中定义的execute方法,另外一个是ExecutorService提供的submit,这两种方式的区别是execute直接执行提交的任务,而submit方法是提交任务后返回一个Future,通过Futur.get()我们可以获取到任务执行的结果,但是这种方式会阻塞当前的线程执行直到拿到返回结果,针对这种情况jdk8增加来CompletableFuture 异步执行的Future,这个东西我们后面再来针对的分析。

接下来我们看看如何创建TheadPoolExecutor,通过构造函数我们逐一说明一下各个参数的作用。

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler)

corePoolSize 核心线程数

  • 核心线程会一直存活,即使没有任务需要执行
  • 当线程数小于核心线程数时,即使有线程空闲,线程池也会优先创建新线程处理
  • 设置allowCoreThreadTimeout=true(默认false)时,核心线程会超时关闭

maximumPoolSize 最大线程数

  • 当线程数>=corePoolSize,且任务队列已满时。线程池会创建新线程来处理任务
  • 当线程数=maxPoolSize,且任务队列已满时,线程池会执行拒绝策略

keepAliveTime 线程空闲时间

  • 当线程空闲时间达到keepAliveTime时,线程会退出,直到线程数量=corePoolSize
  • 如果allowCoreThreadTimeout=true,则会直到线程数量=0

TimeUnit 时间单位

workQueue 任务队列,用来指定线程池用什么队列来装载提交的任务。

  • 如果已创建线程数小于corePoolSize,那么会创建新的线程来执行当前提交的任务,而不是进入阻塞队列
  • 如果已创建线程数大于等于corePoolSize,会尝试先进入阻塞队列,如果进入失败(其实就是队列已满),则会在maxPoolSize条件下创建新的线程来执行当前提交的任务。如果不满足maxPoolSize条件,那么就会执行 拒绝执行策略(默认的拒绝执行策略见下)
  • 通常有三种入队列策略
    1. 直接传递给线程(Direct handoffs)
      比如:SychronousQueue

感觉可以理解为这个入队列会总是失败,就相当于没有这个队列一样。这样就能在maxPoolSize条件下尽可能快的创建(或选择空闲的线程)来执行新提交的任务。
如果提交的任务有互相的依赖性,可以考虑使用这种队列。

public static ExecutorService newCachedThreadPool() {
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                  60L, TimeUnit.SECONDS,
                                  new SynchronousQueue<Runnable>());
}
  1. 无界队列(Unbounded Queue)
    比如:LinkedBlockingQueue
    可以理解为如果有任务需要入队列,那么总会入队成功。
    因此按照创建新线程的条件,理论上不会有超过corePoolSize个数的线程。也就是说理论上线程数最多为corePoolSize,因此maxPoolSize的设置也就显得没有意义了。如果提交的任务互相间没有依赖性,可以考虑使用这种队列
  2. 有界队列(Bounded Queue)
    比如:ArrayBlockingQueue
    如果使用有限个maxPoolSize,那么使用这种队列可以防止资源的耗尽。
    使用长队列和小的线程池,可以降低CPU使用率,降低系统资源的消耗,以及降低线程上下文切换的消耗,但是会导致低吞吐量。如果任务频繁的阻塞,系统可能会创建比允许的线程数多的线程。
    使用短队列和大的线程池,可以提高CPU使用率,但也有可能导致吞吐量下降。

threadFactory 线程工程,用来创建线程

handler 拒绝策略,当线程池已经满的时候再添加新的线程进来以什么方式进行处理,目前提供了四种

  • CallerRunsPolicy 这个拒绝处理器,将直接运行这个任务的run方法。但是,请注意并不是在ThreadPoolExecutor线程池中的线程中运行,而是直接调用这个任务实现的run方法
  • AbortPolicy 这个处理器,在任务被拒绝后会创建一个RejectedExecutionException异常并抛出
  • DiscardPolicy DiscardPolicy处理器,将会默默丢弃这个被拒绝的任务,不会抛出异常,也不会通过其他方式执行这个任务的任何一个方法,更不会出现任何的日志提示
  • DiscardOldestPolicy 这个处理器很有意思。它会检查当前ThreadPoolExecutor线程池的等待队列。并调用队列的poll()方法,将当前处于等待队列列头的等待任务强行取出,然后再试图将当前被拒绝的任务提交到线程池执行

相关文章

  • Java:线程池Executors.newFixedThread

    摘要:Java,多线程,线程池 多线程编程和线程池概述 (1)多线程程序: 计算机可以实现多任务 ( multit...

  • 10.3多线程详解

    Java高级-多线程 多线程创建 多线程通讯 线程池 1.多线程创建 thread/runnable图:继承Thr...

  • 线程

    Java 并发编程:线程池的使用 Java 并发编程:线程池的使用java 多线程核心技术梳理 (附源码) 本文对...

  • Java源码-线程池

    一、线程池实现原理 Java支持多线程,多线程可以提高任务的执行效率。但是Java里面的线程跟操作系统的线程是一一...

  • Java面试题——多线程

    Java面试题——多线程 1,什么是线程池? 线程池是多线程的一种处理方式,处理过程中将任务提交给线程池,任务执行...

  • 阿里巴巴Java高级岗必问面试题总结:JVM+多线程+网络+Re

    阿里巴巴Java高级岗必问面试题总结 一、Java多线程相关 线程池的原理,为什么要创建线程池?创建线程池的方式;...

  • 线程的并发工具类

    Java 下多线程的开发我们可以自己启用多线程,线程池,除此之外,Java还为我们提供了Fork-Join、Cou...

  • [第三期:JAVA并发:线程池管理 ThreadPoolExec

    源码不会骗你的!!! 一、背景 JAVA通过多线程的方式实现并发,为了方便线程池的管理,JAVA采用线程池的方式对...

  • 线程池任务执行过程

    前言 JAVA通过多线程的方式实现并发,为了方便线程池的管理,JAVA采用线程池的方式对线线程的整个生命周期进行管...

  • 线程池底层原理

    概述 JAVA通过多线程的方式实现并发,为了方便线程池的管理,JAVA采用线程池的方式对线线程的整个生命周期进行管...

网友评论

      本文标题:java多线程-线程池

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