线程池ThreadPoolExecutor

Posted 风泊月

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线程池ThreadPoolExecutor相关的知识,希望对你有一定的参考价值。

引子

线程的创建和销毁比较消耗资源,所以有一种更加高效快捷的方式管理线程----线程池。 先来看一下线程池的java模型

  • Executor:线程池顶级接口,只有一个方法

  • ExecutorService:真正的线程池接口

    • void execute(Runnable command) :执行任务/命令,没有返回值,一般用来执行Runnable
    • Future submit(Callable task):执行任务,有返回值,一般又来执行Callable
    • void shutdown() :关闭线程池
  • AbstractExecutorService:基本实现了ExecutorService的所有方法

  • ThreadPoolExecutor:默认的线程池实现类

  • ScheduledThreadPoolExecutor:实现周期性任务调度的线程池

  • Executors:工具类、线程池的工厂类,创建并返回不同类型的线程池

    • Executors.newCachedThreadPool():创建一个可根据需要创建新线程的线程池
    • Executors.newFixedThreadPool(n); 创建一个可重用固定线程数的线程池
    • Executors.newSingleThreadExecutor() :创建一个只有一个线程的线程池
    • Executors.newScheduledThreadPool(n):创建一个线程池,它可安排在给定延迟后运行命令或者定期地执行。
  • 线程池ThreadPoolExecutor参数

  public ThreadPoolExecutor(int corePoolSize, 
          int maximumPoolSize, 
          long keepAliveTime, 
          TimeUnit unit, 
          BlockingQueue<Runnable> workQueue, 
          ThreadFactory threadFactory, 
          RejectedExecutionHandler handler)  
 
  • corePoolSize:核心池的大小
    • 默认情况下,创建了线程池后,线程数为0,当有任务来之后,就会创建一个线程去执行任务。
    • 但是当线程池中线程数量达到corePoolSize,就会把到达的任务放到队列中等待。
  • maximumPoolSize:最大线程数。
    • corePoolSize和maximumPoolSize之间的线程数会自动释放,小于等于corePoolSize的不会释放。当大于了这个值就会将任务由一个丢弃处理机制来处理。
  • keepAliveTime:线程没有任务时最多保持多长时间后会终止
    • 默认只限于corePoolSize和maximumPoolSize间的线程
  • TimeUnit
    • keepAliveTime的时间单位
  • BlockingQueue
    • 存储等待执行的任务的阻塞队列,有多种选择,可以是顺序队列、链式队列等。
  • ThreadFactory
    • 线程工厂,默认是DefaultThreadFactory,Executors的静态内部类
  • RejectedExecutionHandler
    • 拒绝处理任务时的策略。如果线程池的线程已经饱和,并且任务队列也已满,对新的任务应该采取什么策略。
    • 比如抛出异常、直接舍弃、丢弃队列中最旧任务等,默认是直接抛出异常。
      1、CallerRunsPolicy:如果发现线程池还在运行,就直接运行这个线程
      2、DiscardOldestPolicy:在线程池的等待队列中,将头取出一个抛弃,然后将当前线程放进去。
      3、DiscardPolicy:什么也不做
      4、AbortPolicy:java默认,抛出一个异常:

线程池的例子:

/**
 * 使用线程池执行大量的Callable任务
 */
public class TestThreadPool2 
    public static void main(String[] args) throws ExecutionException, InterruptedException 
        //1.创建一个线程池
        //1.创建一个线程池
        //线程池中只有一个线程Single
        //ExecutorService pool = Executors.newSingleThreadExecutor();
        //线程池中有固定数量的线程Fixed
        //ExecutorService pool = Executors.newFixedThreadPool(10);
        //线程池中线程的数量可以动态的变化(增长减少) Cached
        ExecutorService pool = Executors.newCachedThreadPool();


        //2.使用线程池执行大量的Callable任务
        List<Future> futureList = new ArrayList<Future>();
        for (int i = 0; i <20 ; i++) 
            final int n = i;
            //n=5;
            //Callable task = new MyCallable();
            Callable<Integer> task = new Callable<Integer>() 
                @Override
                public Integer call() throws Exception 
                    System.out.println("线程开始:"+n);
                    Thread.sleep(3000);
                    int result = new Random().nextInt(10);
                    System.out.println("线程结束:"+n);
                    return result;
                
            ;
            Future<Integer> future = pool.submit(task);
            futureList.add(future);
            //int result = future.get();//????
            //System.out.println(result);
        

        for (int i = 0; i < 20; i++) 
           Future future=  futureList.get(i);
            System.out.println(future.get());
        

        //3.关闭线程池
        pool.shutdown();
        ForkJoinTask task;
        ForkJoinWorkerThread thread;
    

以上是关于线程池ThreadPoolExecutor的主要内容,如果未能解决你的问题,请参考以下文章

线程池java线程池ThreadPoolExecutor

JavaFX 多线程之 ThreadPoolExecutor 线程池

ThreadPoolExecutor线程池设计思路

ThreadPoolExecutor线程池设计思路

线程池源码分析之ThreadPoolExecutor

ThreadPoolExecutor线程池?