线程池原理

  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.acc = System.getSecurityManager() == null ?
    null :
    AccessController.getContext();
    this.corePoolSize = corePoolSize;
    this.maximumPoolSize = maximumPoolSize;
    this.workQueue = workQueue;
    this.keepAliveTime = unit.toNanos(keepAliveTime);
    this.threadFactory = threadFactory;
    this.handler = handler;
    }

corePoolSize 核心线程数;
maximumPoolSize 最大线程数;
keepAliveTime 空闲线程数存活时间;
TimeUnit  时间格式;
BlockingQueue 工作阻塞队列;
threadFactory 线程工厂;
RejectedExecutionHandler 拒绝策略。

我们知道java中Executors提供了三种创建线程池的方法:

    //默认单个线程
        ExecutorService executorService =Executors.newSingleThreadExecutor();
        //指定线程数
        ExecutorService executorService2 =Executors.newFixedThreadPool(3);
        //带缓存可扩容数最大Integer.MAX_VALUE
        ExecutorService executorService3 =Executors.newCachedThreadPool();

前两者使用的阻塞队列为LinkedBlockingQueue,链表阻塞队列,虽然是有界队列,

但是它最大值为Integer.MAX_VALUE,21亿左右,容易产生OOM问题;所以需要

使用线程池时,需要我们自己手写线程池,并配上对应七大参数;

其中最大核心数要根据服务环境的cpu数来配置:

Runtime.getRuntime().availableProcessors();//获取可用cpu核心数

cpu密集型:core + 1
io密集型: core / (1 - 阻塞系数)或者core * 2 //阻塞系数(0.8-0.9)

RejectedExecutionHandler 默认采用

private static final RejectedExecutionHandler defaultHandler =
        new AbortPolicy();

在超过最大核心数和阻塞队列最大值时会抛出异常,所以不要采用默认拒绝策略。

posted @ 2019-08-26 11:04  748573200000  阅读(196)  评论(0编辑  收藏  举报