zoukankan      html  css  js  c++  java
  • 并发编程之ThreadPoolExecutor源码解析

    本节解析要点如下:

    1、线程池的执行原理

    2、线程是如何复用的

    3、核心线程数如何一直保持、最大线程数如何释放

    4、线上环境线程池应该定义多大

    一 线程池初始化原理

    可参考博客:https://www.jianshu.com/p/23cb8b903d2c

     1 public void execute(Runnable command) {
     2          //如果提交的任务为null  抛出空指针异常*/
     3         if (command == null)
     4             throw new NullPointerException();
     5            
     6         int c = ctl.get();
     7         //如果当前的任务数小于等于设置的核心线程大小,那么调用addWorker直接执行该任务*/
     8         if (workerCountOf(c) < corePoolSize) {
     9             if (addWorker(command, true))
    10                 return;
    11             c = ctl.get();
    12         }
    13         //如果当前的任务数大于设置的核心线程大小,而且当前的线程池状态时运行状态,那么向阻塞队列中添加任务*/
    14         if (isRunning(c) && workQueue.offer(command)) {
    15             int recheck = ctl.get();
    16             if (! isRunning(recheck) && remove(command))
    17                 reject(command);
    18             else if (workerCountOf(recheck) == 0)
    19                 addWorker(null, false);
    20         }
    21         //如果向队列中添加失败,那么就新开启一个线程来执行该任务
    22         else if (!addWorker(command, false))
    23             reject(command);
    24 }
    View Code

    核心要点如下:

    addWorker(Runnable firstTask, boolean core)->w = new Worker(firstTask)->t.start()->runWorker(Worker w)->getTask()->task.run()->addWorker(null, false)

    二 线程如何复用

    请看runWorker方法:runWorker方法里有两个重要方法:getTask() 和 processWorkerExit(w, completedAbruptly)

    线程执行完毕后,会在finally方法里执行processWorkerExit(w, completedAbruptly)方法,此方法会把当前线程重新添加到worker队列,所以线程可以复用

    源码分析如下:

    1、如果当前线程未超过核心线程数,则task不为空,直接执行task.run()方法:具体请看execute和processWorkerExit方法里的区别:

    三 核心线程如何一直保持,最大线程数如何释放

    请关注runWorker方法里有个getTask()方法:

    1、当前线程数小于核心线程数时:timed为false,当前线程一直阻塞,所以核心线程可以一直保持,知道等待有请求加入队列才唤醒执行

    2、当前线程数大于核心线程数:timed为true,workQueue.poll()超时后,进入下次循环,直接return退款while,当前线程释放,即最大线程释放

    四 线上线程池大小如何设置

    1、IO密集型: 最佳线程数目 = ((线程等待时间+线程CPU时间)/线程CPU时间 )* CPU数目

    2、CPU密集型:最佳线程数目 =CPU数目+1

    可以得出一个结论: 
    线程等待时间所占比例越高,需要越多线程。线程CPU时间所占比例越高,需要越少线程。 

  • 相关阅读:
    sublime manjaro
    codeforce 1027C 贪心算法
    codeforce B
    java生成随机数保留数点后两位
    form表单无限提交的问题
    Jquery TimePicker时间箭头无法加载的问题(http://localhost:8080/css/images/ui-icons_444444_256x240.png)
    Mysql 创建事件时出现near‘DO create event...’错误
    线程之实现
    redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool at redis.clients.util.Pool.getResource(Pool.java:53)
    Recursion递归
  • 原文地址:https://www.cnblogs.com/housh/p/13069761.html
Copyright © 2011-2022 走看看