背景
手动创建线程有什么缺点?
- 不受控风险
系统资源有限,每个人针对不同业务都可以手动创建线程,并且创建标准不一样(比如线程没有名字)。当系统运行起来,所有线程都在疯狂抢占资源,无组织无纪律,混乱场面可想而知(出现问题,自然也就不可能轻易的发现和解决)
如果有位神奇的小伙伴,为每个请求都创建一个线程,当大量请求铺面而来的时候,这好比一个正规木马程序,内存被无情榨干耗尽(你无情,你冷酷,你无理取闹)
- 频繁创建开销大
之前发布的《阿里巴巴 Java 手册》里也有一条
线程池的概念
池
池式结构种类
线程池
最大化高并发带来的性能提升,并最小化手动创建线程的风险,将多个线程统一在一起管理的思想
进程池
内存池
数据库连接池
消息队列(消息池)
请求池
池的目的
为了最大化收益,并最小化风险,将资源统一在一起管理的思想
线程池是一种利用池化技术思想来实现的线程管理技术,最大化高并发带来的性能提升,并最小化手动创建线程的风险,将多个线程统一在一起管理的思想。主要是为了复用线程、便于管理线程和任务、并将线程的创建和任务的执行解耦开来。我们可以创建线程池来复用已经创建的线程来降低频繁创建和销毁线程所带来的资源消耗。
线程池优点
降低资源消耗
利用线程池管理并复用已创建的线程来降低创建和销毁线程的消耗,可以控制最大并发数。
提高响应速度
任务到达时,可以不需要等待线程的创建立即执行。
提高线程的可管理性
使用线程池能够统一的分配、调优和监控。将任务的执行和线程的创建以及使用解耦。实现任务线程队列缓存策略和拒绝机制。
线程池可以隔离线程环境,比如,交易服务和搜索服务在同一台服务器上,分别开启两个线程池,交易线程的资源消耗明显要大。因此,通过配置独立的线程池,将较慢的交易服务与搜索服务个离开,避免个服务线程互相影响。
应用场景
日志(文件读写操作)的存储
如在调用日志函数nlog(LEVEL_ERROR,"connect error");,并没有把内容进行落盘,而是把数据交给线程池(任务队列),然后由线程池里面的线程去任务队列中获取数据,进行落盘。这样做的原因是,磁盘比内存访问的速度要慢很多,用线程池方案就可以实现解耦,进而很大程度提高服务器写日志的效率。
日志的优化
尽量精简日志
给日志定级别
适当的增加写日志线程的数量