zoukankan      html  css  js  c++  java
  • java线程池

    通常我们使用线程池均是使用的JDK中自带的线程池,主要有以下几种:

    • newFixedThreadPool 固定线程池
    • newSingleThreadExecutor 单线程池
    • newCachedThreadPool 无限制线程池

    参数介绍

    通过查看Executors源码,可以发现其实际上只是创建了一个ThreadPoolExecutor对象而已。如下代码,可以发现对于固定线程池,实际上是将nThreads设置了ThreadPoolExecutor中的corePoolSize和maximumPoolSize两个参数而已。

    public static ExecutorService newFixedThreadPool(int nThreads) {
            return new ThreadPoolExecutor(nThreads, nThreads,
                                          0L, TimeUnit.MILLISECONDS,
                                          new LinkedBlockingQueue<Runnable>());
        }

    接着看ThreadPoolExecutor的实现逻辑,首先,看下其中的几个参数,毕竟我们所使用的线程池,实际上仅是设置不通的参数而已。

    public ThreadPoolExecutor(int corePoolSize,
                                  int maximumPoolSize,
                                  long keepAliveTime,
                                  TimeUnit unit,
                                  BlockingQueue<Runnable> workQueue,
                                  ThreadFactory threadFactory,
                                  RejectedExecutionHandler handler) 
    • corePoolSize :线程池中保留的线程数量,即使空闲仍然也会保留,除非设置了allowCoreThreadTimeOut,则此时核心线程数为0
    • maximumPoolSize : 线程池中允许创建的最大线程数量,在创建的线程数达到了corePoolSize后,同时,queue中已经满员后,则会继续创建新的线程
    • keepAliveTime : 线程数量大于corePoolSize后,所能保留的最大时间,如果在该时间内没有新的任务,次线程将消亡。
    • unit : 此参数不用多说,因为有时间,必然需要时间单位
    • workQueue : 用于收留那些无法被执行的任务,其将在此处等待被提交执行
    • threadFactory : 线程创建工厂
    • handler : 用于处理那些queue有限制且达到了容量时,那些被阻塞的线程

    抛弃策略

    • AbortPolicy 抛出java.util.concurrent.RejectedExecutionException异常  (默认抛弃策略)
    public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
        throw new RejectedExecutionException("Task " + r.toString() +
                                             " rejected from " +
                                             e.toString());
    }
    • DiscardPolicy 抛弃当前的任务
    public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
    }//不对该任务做出人任何操作
    • DiscardOldestPolicy 抛弃旧的任务
    public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
        if (!e.isShutdown()) {
            e.getQueue().poll();//抛弃最上端的任务
            e.execute(r);//添加新的任务
        }
    }
    • CallerRunsPolicy 在当前线程中执行该任务
    public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
        if (!e.isShutdown()) {//当前线程没有被shutdow
            r.run();//表明在当前吊起该任务的线程中直接执行
        }
    }

    核心方法

    根据参数说明,corePoSize线程不能被回收,且会一直保留,之所以这样,是减少重复创建线程所带来的性能消耗。但是,并非对于这些线程我们无法回收,可以通过allowCoreThreadTimeOut参数来控制,默认值为false,即在线程池消亡前,保留核心线程数量,如果我们设置为ture,则可以将核心线程也一并回收,需要注意一点的是,设置参数的前提是keepAliveTime必须大于0.

    public void allowCoreThreadTimeOut(boolean value) {
        if (value && keepAliveTime <= 0)
            throw new IllegalArgumentException("Core threads must have nonzero keep alive times");
        if (value != allowCoreThreadTimeOut) {
            allowCoreThreadTimeOut = value;
            if (value)
                interruptIdleWorkers();
        }
    }

    关于execute方法,获取当前的Running的线程数量,如果当前线程数量小于corePoolSize,则会直接创建一个新的work进行任务调度

    public void execute(Runnable command) {
        if (command == null)
            throw new NullPointerException();
        int c = ctl.get();
        if (workerCountOf(c) < corePoolSize) {
            if (addWorker(command, true))
                return;
            c = ctl.get();
        }
        if (isRunning(c) && workQueue.offer(command)) {
            int recheck = ctl.get();
            if (! isRunning(recheck) && remove(command))
                reject(command);
            else if (workerCountOf(recheck) == 0)
                addWorker(null, false);//创建一个新的work执行
        }
        else if (!addWorker(command, false))//判断是否已经达到了maximumPoolSize,如果没有,则继续创建新的work
            reject(command);//当前queue中已经存储容量达到上限,则执行抛弃策略
    }
  • 相关阅读:
    使用神经网络识别手写数字Using neural nets to recognize handwritten digits
    C++ 宏定义与常量
    C语言枚举类型(Enum)
    【转】DSP是什么--DSP是神马东东??
    linux 源码编译安装apache
    【转】细说自动化运维的前世今生
    【转】C语言中整型运算取Ceiling问题
    linux系统调优
    linux 状态与系统调优
    vue2.0 watch 详解
  • 原文地址:https://www.cnblogs.com/woniu4/p/9782780.html
Copyright © 2011-2022 走看看