zoukankan      html  css  js  c++  java
  • Java并发机制(7)--线程池ThreadPoolExecutor的使用

    Java并发编程:线程池的使用
    整理自:博客园-海子-http://www.cnblogs.com/dolphin0520/p/3932921.html

    1、什么是线程池,为什么要使用线程池:

      1.1、线程池是线程的集合,里面的线程可以重复使用:java在java.util.concurrent下提供了一个Executor接口及其实现,用于创建管理线程池;线程池是指在初始化一个多线程应用时创建一个线程集合,再需要执行新的任务时,重复使用这些线程,而不是去创建新线程。

      1.2、(1)缩短线程的创建和销毁时间,提高程序的性能;

         (2)根据系统的承受能力,调整线程池中工作线程的数目,防止开销过大造成宕机

      1.3、常用的几种线程池:java doc不建议我么直接使用ThreadPoolExecutor创建线程池,而是使用Executors的静态方法创建;

        (1):Executors.newCachedThreadPool(); 可缓存线程池,可根据需要创建新线程,终止超过60秒空闲的线程。

        (2):Executors.newSingleThreadExecutor(); 只有一个单线程,串行执行所有任务。

        (3):Executors.newFixedThreadPool(int):固定线程数线程池,达到固定数量后不新建也不消除。

    2、Java中的ThreadPoolExecutor类   

      2.1、主要参数:corePoolSize:核心池的大小;maximumPoolSize:最大线程数;keepAliveTime:无任务时线程保持多久会终止;unit:KeepAliveTime的时间单位;workQueue:阻塞队列,存储等待执行的任务;threadFactory线程工厂用来创建线程;hander:拒绝处理任务时的策略;   2.2、继承关系:ThreadPoolExecutor继承自AbstractExecutorService实现了ExecutorService接口继承了Executor接口;   2.3、ThreadPoolExecutor中的主要方法:
        execute():提交任务
        submit():提交任务并返回结果Future;
        shutdown()shutdownNow():关闭线程池;
      2.4、线程池的状态:
        Running(创建时运行)->ShutDown(调用shutdown)/Stop(调用ShutDownNow状态)->Terminated(上一状态,所有线程已销毁,缓存队列已经清空);
      2.5、任务的执行:
        【1】线程池有线程(<corePoolSize)空闲,来任务给空闲线程;
        【2】CorePoolSize已满,尝试将任务进入等待队列,若不成功(workQueue已满)尝试新建线程去执行该任务;
        【3】当前线程池数量达到maximumPoolSize,再来的任务采取拒绝策略(hander)处理任务;
        【4】线程数量超过maximumPoolSize时,若空闲线程的空闲时间超过了keepAliveTime,线程被终止,知道线程数量不大于CorePoolSize;如果允许核心线程设置KeepAliveTime,那么核心线程空闲一定时间后也会被终止。

      2.6、任务缓存队列workQueue及其排队策略:

        workQueue用来存放等待执行的任务,类型为BlockingQueue<Runnable>通常取一下三种类型:

        (1):ArrayBlockingQueue:基于数组的,先进先出,需要指名大小;

        (2):LinkedBlockingQueue:基于链表的先进先出队列,默认大小Integer.MAX_VALUE

        (3):synchronousQueue:不保存任务,直接开启新线程去执行任务。

      2.7、任务拒绝策略:线程池任务缓存队列workQueue以满,且线程池内线程数目达到maximumPoolSize:

        (1):ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。

        (2):ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。

        (3):ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)

        (4):ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务

      2.8、关闭:shutdown()等待所有任务结束,且不接受新任务;shutdownNow():立即关闭,尝试打断正在执行的任务,清空缓存队列。

      2.9、线程池容量动态调整:setCorePoolSize()和setMaximumPoolSize();

    3、:java中ThreadPoolExecutor的使用实例;

      

    public class Test {
         public static void main(String[] args) {   
             ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 10, 200, TimeUnit.MILLISECONDS,
                     new ArrayBlockingQueue<Runnable>(5));
              
             for(int i=0;i<15;i++){
                 MyTask myTask = new MyTask(i);
                 executor.execute(myTask);
                 System.out.println("线程池中线程数目:"+executor.getPoolSize()+",队列中等待执行的任务数目:"+
                 executor.getQueue().size()+",已执行玩别的任务数目:"+executor.getCompletedTaskCount());
             }
             executor.shutdown();
         }
    }
    class MyTask implements Runnable {
        private int taskNum;
         
        public MyTask(int num) {
            this.taskNum = num;
        }
         
        @Override
        public void run() {
            System.out.println("正在执行task "+taskNum);
            try {
                Thread.currentThread().sleep(4000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("task "+taskNum+"执行完毕");
        }
    }
    结果:
    正在执行task 0
    线程池中线程数目:1,队列中等待执行的任务数目:0,已执行玩别的任务数目:0
    线程池中线程数目:2,队列中等待执行的任务数目:0,已执行玩别的任务数目:0
    正在执行task 1
    线程池中线程数目:3,队列中等待执行的任务数目:0,已执行玩别的任务数目:0
    正在执行task 2
    线程池中线程数目:......
    View Code

     4、java.util.concurrent.ThreadPoolExecutor的继承关系

      

  • 相关阅读:
    辅助工具链接
    参考资料链接
    oracle sql 查询前十条数据
    oracle sql 按照汉字规则排序
    oracle sql 修改timestamp数据
    eclipse闪退
    js 数组Array
    面试题:树的子结构
    面试题:二叉树中和为某一路径
    面试题:二叉搜索树的后序遍历
  • 原文地址:https://www.cnblogs.com/whtblog/p/8916190.html
Copyright © 2011-2022 走看看