• 技术文章 >Java >java教程

    深入理解Java ThreadPoolExecutor参数的示例代码分析

    黄舟黄舟2017-03-23 10:25:03原创854
    这篇文章主要介绍了Java ThreadPoolExecutor的参数深入理解的相关资料,需要的朋友可以参考下

    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);
     
     }

    以上就是深入理解Java ThreadPoolExecutor参数的示例代码分析的详细内容,更多请关注php中文网其它相关文章!

    声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。
    上一篇:详解Java虚拟机工作原理(图文) 下一篇:详解java中ThreadLocal本地线程和同步机制的比较实例
    PHP编程就业班

    相关文章推荐

    • 完全掌握java异常处理机制原理和应用• 一起聊聊JAVA中字符串和数组做参数传递• 一起聊聊Java常用数据类型的输入输出• 详细解析Java反射机制原理和几种Class获取方式• 归纳整理Java并发知识点

    全部评论我要评论

  • 取消发布评论发送
  • 1/1

    PHP中文网