• W.T
    2019-06-19
    给李老师点赞👍解析得非常到位!
    
     12
  • 永光
    2019-06-18
    观察 Tomcat 线程池和 Java 原生线程池的区别,其实就是在第 3 步,Tomcat 在线程总数达到最大数时,不是立即执行拒绝策略,而是再尝试向任务队列添加任务,添加失败后再执行拒绝策略。
    问题:
    感觉这两种方式都一样呀,前corePoolSize都是直接创建线程来处理。后续都是先放在队列里面,满了在创建临时线程来处理。 Tomcat线程池,在达到max时 再次检测,并尝试插入队列有什么意义呢?我理解再次检测队列也是满的呀?
    2、

    作者回复: 有可能第一次尝试放队列是满的,失败,再尝试创建临时线程,也满了,但是这个过程中,队列中的任务可能被临时线程消费了一部分,再往队列中送可能会成功。

     4
     6
  • 世纪猛男
    2019-06-18
    关于今日的思考题 getPoolSize. 用Volatile去修饰一个变量不可行,因为变更过程,会基于之前的pool size,无法做到原子操作。 用atomic 也不合适 并发量高的时候 会导致 大量的更新失败, 持续消耗CPU。 所以还不如加锁来的痛快。 请教老师的想法

    作者回复: 可以加锁,但是没有必要多次调用,调一次把结果存起来就行。

     1
     3
  • 吃饭饭
    2019-07-17
    老师,TaskQueue 重写了 offer 方法的关键是什么?是 TaskQueue(int capacity) ,只是把无界变有界了吗?每台看明白 offer 具体的改变是什么

    作者回复: offer方法返回false表示添加失败,添加失败就会创建新线程。

    TaskQueue的父类总是返回true,但是TaskQueue就不会总是返回true了,可能是false,区别在这里。

    
     1
  • calljson
    2019-07-02
    空闲线程到队列取任务,能否讲解下原理,最好附上源码,谢谢
    
     1
  • 13963865700
    2019-06-26
    老师,您好,请问:
    1.Tomcat在默认队列长度无限制的情况下,是不是不会触发拒绝策略,即使线程数达到maxQueueSize也一直把任务放队列中?
    2.这种情况会不会拖垮Tomcat,发生内存溢出?

    作者回复: 为了解决这个问题,Tomcat的定制版任务队列TaskQueue 重写了 LinkedBlockingQueue 的 offer 方法,在合适的时机返回 false,返回 false 表示任务添加失败,这时线程池会创建新的线程。

    
     1
  • -W.LI-
    2019-06-20
    李老师好。我有个问题,原生队列是在队列满时新建线程处理。然后当线程达到最大线程数的时候,不就是队列已满,线程也开满了么。Tomcat补获异常后再往队列里放一次,只是为了做后的努力争取不丢任务么?

    作者回复: 对的

    
     1
  • z.l
    2019-06-18
    感觉直接读workers.size()就可以了么,因为创建线程和销毁线程的方法都加锁了,而且是同一把锁,不懂为啥getPoolSize()方法还要额外加锁?

    作者回复: 是的,这个地方Tomcat的实现可以简化。

     2
     1
  • 迎风劲草
    2019-06-18
    老师,核心线程如果超过keeplive时间,是否也会回收?还有如果我的队列中还有等待执行的runable,这时候kill 进程,时候需要等到所有runable被执行要,进程才结束吗?

    作者回复: 1.可以调用ThreadPoolExecutor的这个方法来指定是否回收核心线程:
    public void allowCoreThreadTimeOut(boolean value)

    2.kill进程会立即退出,内核会负责清理这个进程的所有资源。

    
     1
  • Liam
    2019-06-18
    可以用atomic原子变量替换锁吧
     1
     1
  • sun留白
    2020-01-01
    请问老师,java的原线程池中队列参数时游街递增的吗?我翻看其他的资料里面写的是tomacat和java原线程池中的queue参数都是游街自增,那么是不是这两者都是不会报错,都是队列长度不够再自动增加一下,可以继续往队列里加任务?
    
    
  • ylw666
    2019-11-04
    如果总线程数达到 maximumPoolSize,执行拒绝策略
    ======是队列满才执行拒绝策略吧,不是总线程数达到 maximumPoolSize执行拒绝策略,难道是我理解错了?
    
    
  • 小美
    2019-10-17
    tomcat线程池和jdk线程池使用场景上有什么区别呢老师?因为正常思维阻塞队列是做一个缓冲,为什么jdk要使用这么一种违反常理的设计?
    
    
  • 吴大山
    2019-10-14
    Tomcat 线程池扩展了原生的 ThreadPoolExecutor,通过重写 execute 方法实现了自己的任务处理逻辑:
    1. xxx
    2. 再来任务的话,就把任务添加到任务队列里让所有的线程去抢,如果队列满了就创建临时线程。
    3. xxx
    4. xxx

    我细看了一下第二步代码:
    方法定位:org.apache.tomcat.util.threads.TaskQueue#offer
    逻辑定位:if (parent.getPoolSize()<parent.getMaximumPoolSize()) return false;

    这么看逻辑好像是:再来任务的话,如果线程数少于maximumPoolSize时,都会优先使用线程,而不会入队
    展开
    
    
  • Geek_00d567
    2019-09-19
    getPoolSize,加了重入锁ReentrantLock。可以考虑信号量做控制。
    
    
  • jaryoung
    2019-08-28
    课后题,获取一次设置成一个局部变量,局部变量属于线程安全,无惧
    
    
  • 楊_宵夜
    2019-08-26
    李老师好,getPoolSize()不是动态变化的吗?如果调用一次够缓存起来,缓存的值是不是会存在一致性问题呢?
    
    
  • Wiggle Wiggle
    2019-08-26
    CachedThreadPool 中 Cached 有什么意思?看它定制的 ThreadPool 并没有 cached 的感觉
    
    
  • gogo
    2019-08-13
    结合老师的讲解去看,印象会更深刻,脉络和细节点也会变得清晰,给老师点赞!

    作者回复: 谢谢

    
    
  • brianway
    2019-08-07
    所以通过重写TaskQueue的offer方法,达到的效果就是将无界队列变成了有界队列,且队列长度限制=当前线程数,不知道我理解的对不对。举个例子,corePoolSize=4,maximumPoolSize=10,那来一个任务起一个线程,直到线程数为4,然后再来的任务就入队列,如果队列里任务积累到4个,随着任务继续增多,会新起线程处理,队列长度限制也会依次变成5,6,7,8,一直到10。
     2
    
我们在线,来聊聊吧