zoukankan      html  css  js  c++  java
  • J.U.C线程池

    线程的创建和切换都是代价比较大的。所以,我们需要有一个好的方案能做到线程的复用,这就涉及到一个概念——线程池。合理的使用线程池能够带来3个很明显的好处:

    1. 降低资源消耗:通过重用已经创建的线程来降低线程创建和销毁的消耗
    2. 提高响应速度:任务到达时不需要等待线程创建就可以立即执行。
    3. 提高线程的可管理性:线程池可以统一管理、分配、调优和监控。

    1 线程池状态

    线程池同样有五种状态:Running, SHUTDOWN, STOP, TIDYING, TERMINATED。

        private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
        private static final int COUNT_BITS = Integer.SIZE - 3;
        private static final int CAPACITY   = (1 << COUNT_BITS) - 1;
    ​
        // runState is stored in the high-order bits
        private static final int RUNNING    = -1 << COUNT_BITS;//对应的高3位值是111
        private static final int SHUTDOWN   =  0 << COUNT_BITS;//对应的高3位值是000
        private static final int STOP       =  1 << COUNT_BITS;//对应的高3位值是001
        private static final int TIDYING    =  2 << COUNT_BITS;//对应的高3位值是010
        private static final int TERMINATED =  3 << COUNT_BITS;//对应的高3位值是011
    // Packing and unpacking ctl
        private static int runStateOf(int c)     { return c & ~CAPACITY; }
        private static int workerCountOf(int c)  { return c & CAPACITY; }
        private static int ctlOf(int rs, int wc) { return rs | wc; }

    变量ctl定义为AtomicInteger ,记录了“线程池中的任务数量”和“线程池的状态”两个信息。共32位,其中高3位表示”线程池状态”,低29位表示”线程池中的任务数量”。

    • RUNNING:处于RUNNING状态的线程池能够接受新任务,以及对新添加的任务进行处理。

    • SHUTDOWN:处于SHUTDOWN状态的线程池不可以接受新任务,但是可以对已添加的任务进行处理。

    • STOP:处于STOP状态的线程池不接收新任务,不处理已添加的任务,并且会中断正在处理的任务。

    • TIDYING:当所有的任务已终止,ctl记录的”任务数量”为0,线程池会变为TIDYING状态。当线程池变为TIDYING状态时,会执行钩子函数terminated()。terminated()在ThreadPoolExecutor类中是空的,若用户想在线程池变为TIDYING时,进行相应的处理;可以通过重载terminated()函数来实现。

    • TERMINATED:线程池彻底终止的状态。

    2 构造方法

    线程池参数最全的构造方法

    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

      线程池中核心线程的数量(也称为线程池的基本大小)。当提交一个任务时,线程池会新建一个线程来执行任务,直到当前线程数等于corePoolSize。如果调用了线程池的prestartAllCoreThreads()方法,线程池会提前创建并启动所有基本线程。

    • maximumPoolSize

      线程池中允许的最大线程数。线程池的阻塞队列满了之后,如果还有任务提交,如果当前的线程数小于maximumPoolSize,则会新建线程来执行任务。注意,如果使用的是无界队列,该参数也就没有什么效果了。

    • keepAliveTime

      线程空闲的时间。线程的创建和销毁是需要代价的。线程执行完任务后不会立即销毁,而是继续存活一段时间:keepAliveTime。默认情况下,该参数只有在线程数大于corePoolSize时才会生效。

    • unit

      keepAliveTime的单位。TimeUnit

    • workQueue

      用来保存等待执行的任务的BlockQueue阻塞队列,等待的任务必须实现Runnable接口。选择如下:

      ArrayBlockingQueue:基于数组结构的有界阻塞队列,FIFO。 LinkedBlockingQueue:基于链表结构的有界阻塞队列,FIFO。 PriorityBlockingQueue:具有优先级别的阻塞队列。 SynchronousQueue:不存储元素的阻塞队列,每个插入操作都必须等待一个移出操作。

    • threadFactory

      用于设置创建线程的工厂。ThreadFactory的作用就是提供创建线程的功能的线程工厂。他是通过newThread()方法提供创建线程的功能,newThread()方法创建的线程都是“非守护线程”而且“线程优先级都是默认优先级”。

    • handler

      RejectedExecutionHandler,线程池的拒绝策略。所谓拒绝策略,是指将任务添加到线程池中时,线程池拒绝该任务所采取的相应策略。当向线程池中提交任务时,如果此时线程池中的线程已经饱和了,而且阻塞队列也已经满了,则线程池会选择一种拒绝策略来处理该任务。

      线程池提供了四种拒绝策略:

      AbortPolicy:直接抛出异常,默认策略; CallerRunsPolicy:用调用者所在的线程来执行任务; DiscardOldestPolicy:丢弃阻塞队列中靠最前的任务,并执行当前任务; DiscardPolicy:直接丢弃任务; 当然我们也可以实现自己的拒绝策略,例如记录日志等等,实现RejectedExecutionHandler接口即可。

  • 相关阅读:
    线性滤波器(linear filter)与非线性滤波器(non-linear filter)
    线性滤波器(linear filter)与非线性滤波器(non-linear filter)
    80后开网店卖故事:1500多位为感觉而埋单
    [置顶] think in java interview-高级开发人员面试宝典(一)
    Android ToggleButton Example--开关按钮
    UVA 10012 How Big Is It?(暴力枚举)
    Windows远程连接的实现
    系统集成项目管理之项目采购管理
    UVA 165 Stamps (DFS深搜回溯)
    EF操作增删改查
  • 原文地址:https://www.cnblogs.com/zhuyapeng/p/14354456.html
Copyright © 2011-2022 走看看