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

    创建线程的方式:
        a、New Thread (代表真正意义的线程) 有自己的生命周期(start)
        b、Implement Runable 只是重写了run()方法,还是要借助于New Thread() 来创建线程

    一、使用线程池的目的
    (1)减少系统维护线程的开销
    (2)解耦、运行和创建分开
    (3)线程可以复用
    
    二、线程池的使用
    线程池的分类(常用的4类)
    方法名 解释
    newCachedThreadPool() 创建一个根据需要创建新线程的线程池,但在可用时将重新使用以前构造的线程。
    newFixedThreadPool(int nThreads) 创建一个线程池,该线程池重用固定数量的从共享无界队列中运行的线程。
    newSingleThreadExecutor() 创建一个使用从无界队列运行的单个工作线程的执行程序
    newScheduledThreadPool(int corePoolSize) 创建一个线程池,可以调度命令在给定的延迟之后运行,或定期执行。
    三、线程池的原理

    (1)核心参数 -----》ThreadPoolExecutor

    public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }
    

            (a)打开ThreadPoolExecutor源码

    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue){
       this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
            Executors.defaultThreadFactory(), defaultHandler);
    }
    

            其中

    参数名 解释
    int corePoolSize 限定线程池的基本大小
    int maximumPoolSize 最大线程数量
    long keepAliveTime 线程保持的活动时间
    TimeUnit unit 线程保持的活动时间单位
    BlockingQueue workQueue 任务阻塞队列
    defaultHandler 拒绝策略

    (2)状态变化
            (a)ThreadPoolExecutor源码

    private static final int COUNT_BITS = Integer.SIZE - 3;
    private static final int CAPACITY   = (1 << COUNT_BITS) - 1;
    

    COUNT_BITS :一共29位,表示线程数量,剩下高3位表示状态码
    CAPACITY :最大线程数 即2^29,共536870911


            (b)线程池的状态

    private static final int RUNNING    = -1 << COUNT_BITS;
    private static final int SHUTDOWN   =  0 << COUNT_BITS;
    private static final int STOP       =  1 << COUNT_BITS;
    private static final int TIDYING    =  2 << COUNT_BITS;
    private static final int TERMINATED =  3 << COUNT_BITS;
    

            (c)线程池的状态转换图

    (3)线程池的执行
            (a)Execute方法 源码

    int c = ctl.get();//拿到当前线程的状态值(高3位)
    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);
    }
    else if (!addWorker(command, false))
     reject(command);
    
    

    (4)线程池的关闭

    pool.shutdown()或者pool.shutdownNow()之后执行
    while(!isTerminated()){
    }
    
  • 相关阅读:
    Python基础学习参考(四):条件与循环
    Python基础学习参考(三):内置函数
    Python基础学习参考(二):基本语法
    2011的最后一篇博文 写给我自己也写给你们
    前端开发面试题
    常用js操作:
    两个嵌套for循环执行顺序
    在寻找学习js的途中,又发现了好的东西!
    arcgis api for js初学
    解决为什么arcgis api for js的first map里不显示arcgis地图
  • 原文地址:https://www.cnblogs.com/liulong99/p/11885555.html
Copyright © 2011-2022 走看看