Java 的4个线程池

Java的并发包里面,Executors下面

  • newCachedThreadPool
  • newFixedThreadPool(5)
  • newScheduledThreadPool(3)
  • newSingleThreadExecutor

    /**
     * 线程池的类型
     * 线程池的作用
     * 线程池的原理
     */
    fun runCachedPool(){
        runPool("cached",10,Executors.newCachedThreadPool())
    }
    
    fun runFixedPool(){
        runPool("fixed",10,Executors.newFixedThreadPool(5))
    }
    
    fun runSchedulePool(){
        runPool("schedule",10,Executors.newScheduledThreadPool(3))
    }
    
    fun runSinglePool(){
        runPool("Single",10,Executors.newSingleThreadExecutor())
    }
    
    private fun runPool(method:String, nums:Int, executor: ExecutorService){
        println("run $method start")
        val countDownLatch = CountDownLatch(nums)
        for(i in 0 until nums){
            executor.submit(ThreadClz("$method ${i+1}",countDownLatch))
        }
        executor.shutdown()
        countDownLatch.await()
        println("run $method end")
    }
    
    class ThreadClz(var name:String, private var countDownLatch: CountDownLatch):Runnable{
    
        override fun run() {
            println("id:${Thread.currentThread().id}_$name running,time:${toYYMMDDHHmmssSSS()} start @${Thread.currentThread().name}")
            Thread.sleep(2000)
            println("id:${Thread.currentThread().id}_$name running,time:${toYYMMDDHHmmssSSS()} end")
            countDownLatch.countDown()
        }
    
        @SuppressLint("SimpleDateFormat", "WeekBasedYear")
        fun toYYMMDDHHmmssSSS():String{
            val date = Date()
            val sdf = SimpleDateFormat("YYYY/MM/dd HH:mm:ss.SSS")
            return sdf.format(date)
        }
    
    }

    newCachedThreadPool

    fun runCachedPool(){
        runPool("cached",10,Executors.newCachedThreadPool())
    }
    run cached start
    id:20_cached 1 running,time:2021/01/14 17:56:23.868 start @pool-3-thread-1
    id:21_cached 2 running,time:2021/01/14 17:56:23.868 start @pool-3-thread-2
    id:22_cached 3 running,time:2021/01/14 17:56:23.868 start @pool-3-thread-3
    id:23_cached 4 running,time:2021/01/14 17:56:23.868 start @pool-3-thread-4
    id:25_cached 6 running,time:2021/01/14 17:56:23.869 start @pool-3-thread-6
    id:24_cached 5 running,time:2021/01/14 17:56:23.869 start @pool-3-thread-5
    id:26_cached 7 running,time:2021/01/14 17:56:23.869 start @pool-3-thread-7
    id:27_cached 8 running,time:2021/01/14 17:56:23.869 start @pool-3-thread-8
    id:28_cached 9 running,time:2021/01/14 17:56:23.870 start @pool-3-thread-9
    id:29_cached 10 running,time:2021/01/14 17:56:23.870 start @pool-3-thread-10
    id:21_cached 2 running,time:2021/01/14 17:56:25.870 end
    id:20_cached 1 running,time:2021/01/14 17:56:25.870 end
    id:22_cached 3 running,time:2021/01/14 17:56:25.870 end
    id:26_cached 7 running,time:2021/01/14 17:56:25.873 end
    id:24_cached 5 running,time:2021/01/14 17:56:25.873 end
    id:25_cached 6 running,time:2021/01/14 17:56:25.873 end
    id:23_cached 4 running,time:2021/01/14 17:56:25.873 end
    id:27_cached 8 running,time:2021/01/14 17:56:25.875 end
    id:28_cached 9 running,time:2021/01/14 17:56:25.875 end
    id:29_cached 10 running,time:2021/01/14 17:56:25.875 end
    run cached end

    10个thread同时start,没有看到线程池的影子。。。
    newCachedThreadPool,不限制线程的个数。怎么复用?

    fun runCachedPool(){
        val method = "cached"
        val nums = 10
        val executor = Executors.newCachedThreadPool()
        println("run $method start")
        val countDownLatch = CountDownLatch(nums)
        for(i in 0 until nums/2){
            executor.execute(ThreadClz("$method ${i+1}",countDownLatch))
        }
        Thread.sleep(3000)
        for(i in nums/2 until nums){
            executor.execute(ThreadClz("$method ${i+1}",countDownLatch))
        }
    //        executor.shutdown()
        countDownLatch.await()
        println("run $method end")
    }

    结果如下:

    run cached start
    id:11_cached 1 running,time:2021/01/15 11:54:36.696 start @pool-1-thread-1
    id:14_cached 4 running,time:2021/01/15 11:54:36.696 start @pool-1-thread-4
    id:12_cached 2 running,time:2021/01/15 11:54:36.696 start @pool-1-thread-2
    id:13_cached 3 running,time:2021/01/15 11:54:36.696 start @pool-1-thread-3
    id:15_cached 5 running,time:2021/01/15 11:54:36.696 start @pool-1-thread-5
    id:15_cached 5 running,time:2021/01/15 11:54:38.713 end
    id:14_cached 4 running,time:2021/01/15 11:54:38.713 end
    id:11_cached 1 running,time:2021/01/15 11:54:38.713 end
    id:12_cached 2 running,time:2021/01/15 11:54:38.713 end
    id:13_cached 3 running,time:2021/01/15 11:54:38.713 end
    id:15_cached 8 running,time:2021/01/15 11:54:39.698 start @pool-1-thread-5
    id:11_cached 9 running,time:2021/01/15 11:54:39.698 start @pool-1-thread-1
    id:14_cached 10 running,time:2021/01/15 11:54:39.698 start @pool-1-thread-4
    id:12_cached 7 running,time:2021/01/15 11:54:39.698 start @pool-1-thread-2
    id:13_cached 6 running,time:2021/01/15 11:54:39.698 start @pool-1-thread-3
    id:15_cached 8 running,time:2021/01/15 11:54:41.703 end
    id:11_cached 9 running,time:2021/01/15 11:54:41.703 end
    id:12_cached 7 running,time:2021/01/15 11:54:41.703 end
    id:14_cached 10 running,time:2021/01/15 11:54:41.703 end
    id:13_cached 6 running,time:2021/01/15 11:54:41.703 end
    run cached end

    可以看到,后面5个线程被复用了。所以,cache的线程会保存60s,看来是真的。
    其他的三个,newFixedThreadPool,newScheduledThreadPool
    和newSingleThreadExecutor
    Sinle很简单,就是线程池只有1个线程在跑,其他task都在排队,等待线程空闲。
    其他2个都是会需要输入核心线程的个数,也就是线程池会持有几个线程。

先说结论:

  • newCachedThreadPool,线程数不固定,线程空闲以后,会被回收。
  • newFixedThreadPool, 核心线程数固定,最大线程数也是固定。核心线程的概念就是处于IDLE状态,也不会回收。
  • newScheduledThreadPool,核心线程数固定,线程数无上限。它还可以进行delay操作,延迟进行线程运行。
  • newSingleThreadExecutor,保证每个时刻只有1个线程在运行。single可以保证唯一性。线程回收以后,还能重新new一个线程。

发表评论

电子邮件地址不会被公开。 必填项已用*标注