JUC并发编程(3):线程池

谈到线程池,只需要记住这三个词:三大方法,七大参数,四种拒绝策略轻松搞定!

1、线程池

在Java中,创建和销毁线程是非常费时的,可能加起来的运行时间可能远大于方法实行的时间,为了提高程序效率,我们需要尽可能的降低线程的创建和销毁!此时就会使用线程池这种池化技术!

2、三大方法(创建线程池的方法)

ExecutorService ThreadPool1 = Executors.newSingleThreadExecutor();// 单个线程
ExecutorService ThreadPool2 = Executors.newFixedThreadPool(5); // 创建一个固定的线程池的大小
ExecutorService ThreadPool3 = Executors.newCachedThreadPool(); // 可伸缩的,遇强则强,遇弱则弱
//工作中用自定义线程池方法
ExecutorService ThreadPool1 = new ThreadPoolExecutor( 
                2,//核心线程池大小
                5,//最大线程池大小
                3,//超时了没有人用就会释放
                TimeUnit.SECONDS,//释放时间超时单位
                new LinkedBlockingDeque<>(3), //阻塞队列
                Executors.defaultThreadFactory(),//线程工厂
                new ThreadPoolExecutor.AbortPolicy());//拒绝策略

用完线程池之后一定要关闭线程池

ThreadPool3.shutdown();

3、七大参数(自定义线程池:推荐)

底层都是返回一个new 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;
}

最大线程如何设置?

int maximumPoolSize——最大线程池大小 ! 调优!

  • CPU密集型,CPU是几核,就在最大线程池数量定义为几,可以用Runtime.getRuntime().availableProcessors();判断
  • IO密集型,判断程序中十分耗IO的线程,大于改值即可

线程池业务逻辑!

  • 多个线程同时进行时,首先获取核心线程池
  • 如果核心线程池使用满了,下面的线程会进入阻塞队列等待
  • 如果阻塞队列满了,则会开启最大线程池数量
  • 如果最大线程池占用满了,阻塞队列满了,则会执行拒绝策略
  • 如果线程执行完了超时没人用,最大线程数量释放,保留核心线程数量

5、四种拒绝策略(线程超量处理方法)

java   new ThreadPoolExecutor.AbortPolicy()//如果线程超量则抛出异常   
new ThreadPoolExecutor.CallerRunsPolicy()//如果线程超量则在主线程执行   
new ThreadPoolExecutor.DiscardOldestPolicy()//如果线程超量则丢掉任务,不会抛出异常   
new ThreadPoolExecutor.DiscardPolicy()//如果线程超量则尝试竞争丢掉任务不会抛出异常 
原文地址:https://www.cnblogs.com/huangwentian/p/14663006.html