Java线程池知识总结

Java线程池知识总结

为什么会有线程池

  • 创建线程开销大,主要是时间和内存开销。

    Java线程是映射到操作系统用户线程,创建时需要分配栈空间、计数器等。占用空间大小由-Xss控制,默认是1M。

  • 每次手动创建线程难管理。

    机器的CPU和内存资源能支持的线程数是有限的,创建过多的线程会争抢CPU和占用过多内存,造成程序响应慢甚至“假死”。

线程池原理

  • 数据库连接池等池化资源,一般使用流程:获取资源 -> 执行操作 -> 归还资源。

  • 线程池则不同,实现方式是:生产者-消费者模式

    线程池使用方是生产者,生产任务;线程池是消费者,每个Worker线程循环获取任务执行。

    循环获取任务源码参考java.util.concurrent.ThreadPoolExecutor.runWorker(Worker)

核心线程数corePoolSize、最大线程数maximumPoolSize、缓冲队列workQueue、拒绝策略RejectedExecutionHandler怎么起效的?

  1. 先根据核心线程数corePoolSize创建线程,当核心线程都忙还有新任务来时,任务就进入缓冲队列workQueue;

  2. 当缓冲队列满时,再根据最大线程数maximumPoolSize创建新线程(触发创建新线程的那个任务就是这个线程的第一个任务);

  3. 当达到最大线程数还有任务来时,则执行拒绝策略RejectedExecutionHandler。

为什么是上述策略?

线程池的设计目标是重用线程。如果一出现任务堆积就新建线程,可能会导致频繁创建销毁线程,与线程池设计目标相违背。

线程池使用注意事项

  • 给线程指定有意义的名字。

    仿照java.util.concurrent.Executors.DefaultThreadFactory实现自定义ThreadFactory,或者在spring框架下使用org.springframework.scheduling.concurrent.CustomizableThreadFactory。

  • 使用有界队列做缓冲区。

    使用ArrayBlockingQueue或者带capacity的LinkedBlockingDeque,避免OOM;避免使用Executors工厂方法创建线程池。

  • 代码捕获所有异常。

    线程池执行任务时遇到RuntimeException不会有任何信息,遇到问题不方便排查。

	run(){
		try{
			//do job
		}catch(Throwable e){
			//自定义处理
		}
	}

线程池不是银弹

我们不能仅仅因为程序慢,就使用线程池异步执行,重要的还是程序的执行效率。

更多参考

美团这篇文章图文并茂,深入讲解线程池实现原理及动态线程池方案。Java线程池实现原理及其在美团业务中的实践

一种动态线程池方案实现。yinjihuan的动态线程池方案实现

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值