Java ThreadPoolExecutor的参数深入理解

作者:Lubby 时间:2022-08-29 10:08:39 

Java ThreadPoolExecutor的参数深入理解

一、使用Executors创建线程池   

        之前创建线程的时候都是用的Executors的newFixedThreadPool(),newSingleThreadExecutor(),newCachedThreadPool()这三个方法。当然Executors也是用不同的参数去new ThreadPoolExecutor

    1. newFixedThreadPool()

    创建线程数固定大小的线程池。 由于使用了LinkedBlockingQueue所以maximumPoolSize 没用,当corePoolSize满了之后就加入到LinkedBlockingQueue队列中。每当某个线程执行完成之后就从LinkedBlockingQueue队列中取一个。所以这个是创建固定大小的线程池。


public static ExecutorService newFixedThreadPool(int nThreads) {
   return new ThreadPoolExecutor(nThreads, nThreads,
                  0L, TimeUnit.MILLISECONDS,
                  new LinkedBlockingQueue<Runnable>());
 }
public ThreadPoolExecutor(int corePoolSize,
              int maximumPoolSize,
              long keepAliveTime,
              TimeUnit unit,
              BlockingQueue<Runnable> workQueue) {
  this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
      Executors.defaultThreadFactory(), defaultHandler);
 }

   2.newSingleThreadPool()

    创建线程数为1的线程池,由于使用了LinkedBlockingQueue所以maximumPoolSize 没用,corePoolSize为1表示线程数大小为1,满了就放入队列中,执行完了就从队列取一个。


public static ExecutorService newSingleThreadExecutor() {
   return new FinalizableDelegatedExecutorService
     (new ThreadPoolExecutor(1, 1,
                 0L, TimeUnit.MILLISECONDS,
                 new LinkedBlockingQueue<Runnable>()));
 }

    3.newCachedThreadPool()

    创建可缓冲的线程池。没有大小限制。由于corePoolSize为0所以任务会放入SynchronousQueue队列中,SynchronousQueue只能存放大小为1,所以会立刻新起线程,由于maxumumPoolSize为Integer.MAX_VALUE所以可以认为大小为2147483647。受内存大小限制。


public static ExecutorService newCachedThreadPool() {
   return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                  60L, TimeUnit.SECONDS,
                  new SynchronousQueue<Runnable>());
 }
public ThreadPoolExecutor(int corePoolSize,
            int maximumPoolSize,
            long keepAliveTime,
            TimeUnit unit,
            BlockingQueue<Runnable> workQueue) {
   this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
      Executors.defaultThreadFactory(), defaultHandler);
 }

二、使用ThreadPoolExecutor创建线程池

ThreadPoolExecutor的构造函数


public ThreadPoolExecutor(int corePoolSize,
              int maximumPoolSize,
              long keepAliveTime,
              TimeUnit unit,
              BlockingQueue<Runnable> workQueue,
              ThreadFactory threadFactory,
              RejectedExecutionHandler handler) {
   if (corePoolSize < 0 ||
     maximumPoolSize <= 0 ||
     maximumPoolSize < corePoolSize ||
     keepAliveTime < 0)
     throw new IllegalArgumentException();
   if (workQueue == null || threadFactory == null || handler == null)
     throw new NullPointerException();
   this.corePoolSize = corePoolSize;
   this.maximumPoolSize = maximumPoolSize;
   this.workQueue = workQueue;
   this.keepAliveTime = unit.toNanos(keepAliveTime);
   this.threadFactory = threadFactory;
   this.handler = handler;
 }

参数:

        1、corePoolSize核心线程数大小,当线程数<corePoolSize ,会创建线程执行runnable

        2、maximumPoolSize 最大线程数, 当线程数 >= corePoolSize的时候,会把runnable放入workQueue中

        3、keepAliveTime  保持存活时间,当线程数大于corePoolSize的空闲线程能保持的最大时间。

        4、unit 时间单位

        5、workQueue 保存任务的阻塞队列

        6、threadFactory 创建线程的工厂

        7、handler 拒绝策略

任务执行顺序:

        1、当线程数小于corePoolSize时,创建线程执行任务。

        2、当线程数大于等于corePoolSize并且workQueue没有满时,放入workQueue中

        3、线程数大于等于corePoolSize并且当workQueue满时,新任务新建线程运行,线程总数要小于maximumPoolSize

        4、当线程总数等于maximumPoolSize并且workQueue满了的时候执行handler的rejectedExecution。也就是拒绝策略。

ThreadPoolExecutor默认有四个拒绝策略:

        1、ThreadPoolExecutor.AbortPolicy()   直接抛出异常RejectedExecutionException

        2、ThreadPoolExecutor.CallerRunsPolicy()    直接调用run方法并且阻塞执行

        3、ThreadPoolExecutor.DiscardPolicy()   直接丢弃后来的任务

        4、ThreadPoolExecutor.DiscardOldestPolicy()  丢弃在队列中队首的任务

当然可以自己继承RejectedExecutionHandler来写拒绝策略.


int corePoolSize = 1;
int maximumPoolSize = 2;
int keepAliveTime = 10;
// BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<Runnable>();
BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<Runnable>(5);
ThreadFactory threadFactory = Executors.defaultThreadFactory();
//线程池和队列满了之后的处理方式
//1.跑出异常
RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy();
RejectedExecutionHandler handler2 = new ThreadPoolExecutor.CallerRunsPolicy();
RejectedExecutionHandler handler3 = new ThreadPoolExecutor.DiscardPolicy();
RejectedExecutionHandler handler4 = new ThreadPoolExecutor.DiscardOldestPolicy();

ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, TimeUnit.SECONDS, workQueue, threadFactory, handler2);

for (int j = 1; j < 15; j++) {
 threadPoolExecutor.execute(new Runnable() {

public void run() {

try {
  System.out.println(Thread.currentThread().getName());
  TimeUnit.SECONDS.sleep(1);
  } catch (InterruptedException e) {
  e.printStackTrace();
  }

}
 });
}

System.out.println(threadPoolExecutor);

}

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

来源:https://my.oschina.net/u/2250599/blog/498787

标签:Java,ThreadPoolExecutor
0
投稿

猜你喜欢

  • java中sdk与jdk的区别详细解析

    2023-11-25 03:37:14
  • java 注解默认值操作

    2023-08-25 20:31:38
  • Java经验点滴:类注释文档编写方法

    2023-11-06 03:50:11
  • Java遗传算法之冲出迷宫

    2022-01-12 21:34:58
  • springboot搭建访客管理系统的实现示例

    2023-09-02 13:10:41
  • Java算法比赛常用方法实例总结

    2023-11-28 07:15:26
  • SpringBoot项目中如何访问HTML页面

    2021-08-09 11:19:07
  • Java泛型通配符的使用详解

    2022-07-08 14:08:43
  • springboot使用校验框架validation校验的示例

    2021-06-10 18:20:25
  • SpringBoot+netty-socketio实现服务器端消息推送

    2023-11-15 06:14:31
  • 浅谈java中静态方法的重写问题详解

    2022-12-24 10:13:04
  • IOS 实现摇一摇的操作

    2023-07-02 13:46:53
  • Java日期操作方法工具类实例【包含日期比较大小,相加减,判断,验证,获取年份等】

    2023-11-25 12:14:40
  • SpringBoot+Redis实现数据字典的方法

    2022-08-03 14:22:29
  • 浅谈图片上传利用request.getInputStream()获取文件流时遇到的问题

    2023-10-18 10:36:43
  • C++语言io流处理基本操作教程示例

    2023-11-02 22:07:39
  • java实现将数字转换成人民币大写

    2023-08-11 05:07:29
  • java判断http地址是否连通(示例代码)

    2023-08-05 03:24:05
  • SpringBoot日志框架之Log4j2快速入门与参数详解

    2023-11-15 21:17:59
  • Java排序的那些事之sort方法的使用详解

    2023-01-22 00:18:35
  • asp之家 软件编程 m.aspxhome.com