线程池-ThreadPoolExecutor

*流程图参考博客:https://blog.csdn.net/u010723709/article/details/50372322

一、ThreadPoolExecutor构造

      ThreadPoolExecutor类继承AbstractExecutorService类

       AbstractExecutorService类实现ExecutorService接口

      ExecutorService类继承Executor类

二、ThreadPoolExecutor类中的4种构造方法

1).  public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue)

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

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

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

                              RejectedExecutionHandler handler)

三、ThreadPoolExecutor类中的构造方法的参数解释

1).int corePoolSize【核心线程数最大值】

   a.线程池新建线程的时候,会先去比较是否大于核心线程数,小于的情况下创建核心线程,大于的情况下则创建非核心线程数,核心线程数可以通过设置allowCoreThreadTimeOut=true,long keepAliveTime=time【超时时间】来销毁空闲的核心线程,如果不设置该值,则一直存在于线程池中。

2).int maximumPoolSize【线程总数最大值,即核心线程数+非核心线程数】

3).long keepAliveTime【非核心线程闲置超时时间】

   a.一个非核心线程闲置状态下超过keepAliveTime,则销毁该线程,控制核心线程时,需要同时设置allowCoreThreadTimeOut的值为true。

4).TimeUnit unit【keepAliveTime的单位,枚举类型】

NANOSECONDS : 1微毫秒 = 1微秒 / 1000MICROSECONDS : 1微秒 = 1毫秒 / 1000MILLISECONDS : 1毫秒 = 1秒 /1000SECONDS : 秒MINUTES : 分HOURS : 小时DAYS : 天

5).BlockingQueue<Runnable> workQueue【线程池的任务队列】
a.所有核心线程无闲置的情况下,新添加的任务会放入该队列等待处理,如果队列满了,就创建非核心线程执行任务
b.常用的workQueue类型
  ①.SynchronousQueue:接收任务之后直接提交给线程处理,如果线程都在工作,则直接创建线程,因为可以无限创建线程,所以该队列的maximumPoolSize指定为Integer.MZX_VALUE。
  ②.LinkedBlockingQueue:接收任务之后判断当前线程是否小于核心线程数,如果少于则创建核心线程处理任务,如果当前线程数等于核心线程数,则在队列中等待。该队列的大小默认为Integer.MZX_VALUE,可手动设置该队列的大小,即【public LinkedBlockingQueue(int capacity)】
  ③.ArrayBlockingQueue:可以限定队列的长度,如果当前线程数小于核心线程数,创建核心线程处理任务,如果当前线程数达到了核心线程数,则放入队列中等待,如果队列满了,则创建非核心线程处理任务,如果当前总线程数等于maximumPoolSize,对列也满了,则发生错误。
  ④.DelayQueue:队列内元素必须实现Delayed接口,该队列接收到任务,首先先入队列,只有达到了指定的延时时间,才会执行任务。

6).ThreadFactory threadFactory【创建线程的方式,一般用不上】

7).RejectedExecutionHandler handler【异常抛出,一般用不上】

四、提交任务

 通过ThreadPoolExecutor.execute(Runnable command)方法向线程池添加一个任务

五、ThreadPoolExecutor处理任务策略总结

  1、当前线程数小于核心线程数的情况下,创建核心线程数来处理任务
  2、当前线程数等于核心线程数时,放入等待队列
  3、等待队列满时,创建非核心线程处理任务
  4、队列满时,总线程数=maximumPoolSize时,由RejectedExecutionHandler抛出异常

六、常见四种线程池

   Java通过Executors提供了四种线程池,这四种线程池都是直接或间接配置ThreadPoolExecutor的参数实现的
 
 (一)CachedThreadPool()【可缓存线程池】
 
          1、创建方式
               ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
          2、源码
              public static ExecutorService newCachedThreadPool() {
                    return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                             60L, TimeUnit.SECONDS,
                                              new SynchronousQueue<Runnable>());
            }
          3、总结
           1)线程数无限制
           2)有空闲线程则复用空闲线程,若无空闲线程则新建线程
         
 (二)newFixedThreadPool()【定长线程池】
 
          1、创建方式
                ExecutorService fixed = Executors.newFixedThreadPool(int nThreads);
          2、源码
              public static ExecutorService newFixedThreadPool(int nThreads) {
                    return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
            }
          3、总结
               1)、可控制线程最大并发数(同时执行的线程数)
               2)、超出的线程会在队列中等待
        4、例子
           
①实现Runnable接口
public class ThreadTest implements Runnable {

    private String name;

    public ThreadTest(String name) {
        this.name = name;
    }

    @Override
    public void run() {
        System.out.println("hello:" + name);
        try {
            Thread.sleep(6000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
②创建线程池,提交任务
  public static void main(String[] args) {
          //创建了一个线程个数为2的线程池
        ExecutorServer server=Executors.newFixedThreadPool(2);
       while(true){
           //void execute(Runnable command);
            server.execute(new ThreadTest("Thread1"));
            server.execute(new ThreadTest("Thread2"));
            server.execute(new ThreadTest("Thread3"));
            server.execute(new ThreadTest("Thread4"));
       }
 }
③结果:
hello:Thread2
hello:Thread1
//等这两个线程结束任务之后,才会执行3、4
hello:Thread3
hello:Thread4

          
 (三)newScheduledThreadPool()【支持定时及周期性任务执行】
 
          1、创建方式
               ExecutorService scheduledPool = Executors.newScheduledThreadPool(int corePoolSize);
          2、源码
               public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
                    return new ScheduledThreadPoolExecutor(corePoolSize);
              }

             public ScheduledThreadPoolExecutor(int corePoolSize) {
                         super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS,
                                     new DelayedWorkQueue());
            }
     
         3、使用方式
                3.1、延时执行功能【延迟3秒执行Runnable任务】
                       scheduledPool.schedule(Runnable,3,TimeUnit.SENCONDS);
                3.2、 循环执行功能【循环执行任务,首先延迟3秒执行,1小时循环一次】
                        scheduledPool.schedule(Runnable,3,1,TimeUnit.HOURS);
        
 (四)newSingleThreadExecutor()【单线程化的线程池,等同于newFixedThreadPool(1)】
 
          1、创建方式
                ExecutorService singlePool = Executors.newSingleThreadExecutor();
          2、源码
              public static ExecutorService newSingleThreadExecutor() {
                            return new FinalizableDelegatedExecutorService
                                    (new ThreadPoolExecutor(1, 1,
                                            0L, TimeUnit.MILLISECONDS,
                                            new LinkedBlockingQueue<Runnable>()));
            }
          3、总结
              1)、有且仅有一个工作线程执行任务
              2)、所有任务按照指定顺序执行,即遵循队列的入队出队规则

七、使用步骤

1)创建实现Runnable接口的线程类,
public runnable implements Runnable(){
     @Override
    public void run() {
       //todo
    }
}
2)根据情况创建线程池
ExecutorService executor=Executors.newFixedThreadPool(2);
3)提交任务到线程池【execute方法 就是对Runnable对象调用start()方法
// void execute(Runnable command);
executor.execute(new runnable());
*参考:https://www.jianshu.com/p/210eab345423
  





   



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值