• I am a psycho
    2018-06-23
    通过看源码可以得知,core和max都是1,而且通过FinalizableDelegatedExecutorService进行了包装,保证线程池无法修改。同时shutdown方法通过调用interruptIdleWorkers方法,去停掉没有工作的线程,而shutdownNow方法是直接粗暴的停掉所有线程。无论是shutdown还是shutdownNow都不会进行等待,都会直接将线程池状态设置成shutdown或者stop,如果需要等待,需要调用awaitTernination方法。查找了一下threadFactory的使用,只找到了在worker创建的时候,用来初始化了线程。

    作者回复: 不错,很棒的总结;
    我问threadFactory次数,其实是问worker都在什么情况下会被创建,比如,比较特别的,任务抛异常时;随便自定义一个threadfactory,模拟提交任务就能体会到

    
     26
  • 三木子
    2018-06-23
    我觉得还有一点很重要,就是放在线程池中的线程要捕获异常,如果直接抛出异常,每次都会创建线程,也就等于线程池没有发挥作用,如果大并发下一直创建线程可能会导致JVM挂掉。最近遇到的一个坑

    作者回复: 任务出异常是要避免

    
     16
  • 约书亚
    2018-06-23
    疑问,为什么当初sun的线程池模式要设计成队列满了才能创建非核心线程?类比其他类似池的功能实现,很多都是设置最小数最大数,达到最大数才向等待队列里加入,比如有的连接池实现。

    作者回复: Doug Lea这个实现基本是工业标准了,除非特定场景需求

     2
     14
  • Harry陈祥
    2019-02-12
    老师您好。有次面试,面试官问:为什么java的线程池当核心线程满了以后,先往blockingQueue中存任务,queue满了以后才会创建非核心线程? 是在问,为什么要这么设计?
    请问这个问题应该怎么回答?
     3
     13
  • 沈琦斌
    2018-06-28
    老师,我想问的是cache的线程池大小是1,每次还要新创建,那和我自己创建而不用线程池有什么区别?

    作者回复: 你是说cachedthreadpool?那个大小是浮动的,不是1;如果说single,executorservice毕竟还提供了工作队列,生命周期管理,工作线程维护等很多事,还是要高效

    
     7
  • nb Ack
    2019-05-22
    阻塞性:
    BlockQueue存入任务队列时是没有阻塞,使用的是offer,无阻塞添加方法。
    BlockQueue取出任务队列时是有阻塞,有超时使用poll取值,无超时使用take阻塞方法取值

    添加任务逻辑:
    1.当任务数小于核心线程数,新建核心线程来执行任务
    2.任务数大于核心线程数,队列不满,放入任务队列
    3.任务数大于核心线程数,队列已满,新建线程执行
    4.任务数大于核心线程数,队列已满,工作线程已达最大线程数,拒绝任务,抛出异常(而不是阻塞任务,等待进入队列)
    展开
    
     3
  • 饭粒
    2019-01-15
    写了个简单demo玩了下。
    创建线程池会初始化线程工厂,工作线程是在提交任务的创建的。工作线程在执行任务中抛出异常,再次提交任务会又新建工作线程。newFixedThreadPool 正常执行任务时会优先创建线程已达到核心线程数,不会优先复用空闲工作线程。
    ```
    /**
     * 线程池工作线程执行任务抛出异常
     */
    @Test
    public void test03() throws InterruptedException {
        // java.util.concurrent.Executors.DefaultThreadFactory.DefaultThreadFactory 构造线程工厂
        ExecutorService executorService = Executors.newCachedThreadPool();
        Runnable task = new Runnable() {
            @Override
            public void run() {
                System.out.println("hello world");
                // 抛出异常
                throw new RuntimeException();
            }
        };
        executorService.execute(task);
        // 提交任务通过 DefaultThreadFactory.newThread() 创建线程
        TimeUnit.SECONDS.sleep(2);
        // 前一个工作线程在执行任务中抛出异常,再提交任务又会新建工作线程
        executorService.execute(task);

        TimeUnit.SECONDS.sleep(3);
    }
    ```
    展开

    作者回复: 实践是好习惯

    
     3
  • Ifdevil
    2019-03-04
    老师您好,我看了线程池源码,里面是用HashSet存放worker的,为什么这里用hashset呢?去重?线程池需要去重吗?
    
     2
  • 不告诉你
    2019-02-22
    无论是创建核心线程还是非核心线程,都需要获取全局锁。只有在工作队列满了以后才去创建非核心线程,应该就是为了在时间上尽量延后非核心线程的创建,为了线程池的性能做考虑吧。
    
     2
  • 康
    2019-03-03
    我的理解,设置非核心线程的目的是防止任务数的段时间激增,导致任务数过多,从而核心线程处理时间太长。正常情况下要保证线程数小于核心线程数,非核心线程会过一段时间就被移出,保证了资源的利用,而核心一般不会变少
    
     1
  • 欣
    2018-07-04
    杨老师,我照着文章翻看源码,下面那块是不是不太对?
    ----------------
    Executors 目前提供了 5 种不同的线程池创建配置:

    newSingleThreadExecutor,它创建的是个 FinalizableDelegatedExecutorService

    newSingleThreadScheduledExecutor 创建的是 ScheduledThreadPoolExecutor
    展开

    作者回复: 谢谢指出

     1
     1
  • 镰仓
    2018-06-28
    听了一段时间课程,质量很高。我的需求是android JavaVM

    作者回复: android我并没有特别的经验,尽管很多方面是通用的

    
     1
  • 王磊
    2018-06-25
    core和max应该都是1。验证的方法是自己写一个Threadlocal, 里面有相应创建线程的日志,然后把它传入创建线程池。

    作者回复: core和Max源码或者逻辑分析都很清楚;而创建线程次数理论上是不确定的,比如任务执行中抛异常,就要重新创建worker

    
     1
  • 何義
    2019-12-22
    请教一下,多线程下面是否可以再嵌套多线程
    
    
  • Paul Shan
    2019-11-26
    我个人更倾向于用rxjava解决多线程的问题而不是直接操作线程池。
    
    
  • Paul Shan
    2019-11-26
    newCachedThreadPool() 60s时间窗口缓存线程,适合的场景是系统需要的线程数在每分钟是差不多的。
    newFixedThreadPool(int nThreads),设定了活动线程的最大值,如果超过这个数目,线程进入等待状态。适合场景例如总共只有n个CPU,为了提高效率,最多的并行也就是n。
    newSingleThreadExecutor(),单线程执行,可以保证多个线程的执行顺序。
    newSingleThreadScheduledExecutor() 和 newScheduledThreadPool(int corePoolSize) 周期性调度
    newWorkStealingPool(int parallelism) 并行处理线程
    
    
  • SevenSir
    2019-08-18
    学习了一下,自己总结一下:https://www.jhonrain.org/2018/09/14/%E9%AB%98%E5%B9%B6%E5%8F%91-%E7%BA%BF%E7%A8%8B%E6%B1%A0%E5%89%96%E6%9E%90/
    
    
  • bruce
    2019-08-12
    杨老师,文章中你指出newCachedThreadPool使用于大量短时间任务的场景。大量短时间任务这个是如何定义的,是否可以给出一些具体的业务使用场景。谢谢!
    
    
  • 拯救地球好累
    2019-05-21
    为什么cache线程池用的是大小为0的队列呢?
    
    
  • gogo
    2019-04-28
    core/max size都是1。但是后面的 我就不知道怎么验证了
    
    
我们在线,来聊聊吧