如何避免重复创建线程?创建线程池的方式有哪些?各自优缺点有哪些?

如何避免重复创建线程?创建线程池的方式有哪些?各自优缺点有哪些?

1、案例分析

我们在使用一些app的时候,应该都收到过消息推送,它们往往依赖消息推送服务实现。事实上,互联网大厂都有自己的消息推送服务(又名Message Push Server),通过消息推送服务实现对App的消息推送,不关注掉技术实现的细节,大致过程如图

在这里插入图片描述
如果让你来实现一个消息推送服务,要求保证消息推送的实时性,你会怎么设计呢?

你可能会想到,用多线程技术去做,为每个客户端都创建一个线程,然后启动线程,每来一条需要推送的消息就用创建好的线程发送出去。如图

在这里插入图片描述
每当有一个客户端与服务端建立连接,就创建一个线程来执行消息推送服务

这种方案看起来挺不错,但是可行性如何?其实,这种方案是无法在生产环境实战的。原因就在于不断创建线程这个操作本身是不合理的。

不慌,我们先看一段代码,在循环中一直创建线程,看看会出现什么情况,如图3所示。

在这里插入图片描述
在这里插入图片描述
可以看到控制台出现了java.lang.OutOfMemoryError报错,即内存已用尽。出现这个错误的原因就在于我们创建了太多的线程,线程对象本身以及线程的调用栈都是要占用内存的,而操作系统的内存是有限的,这决定了我们能创建的线程数也是有限制的,而无限制的创建线程会使内存不断消耗最终超过内存上限从而报错。

事实上,能创建多少线程数是有一个计算公式的:可创建的线程数 =(进程的最大内存 – JVM分配的内存 – 操作系统保留的内存)/ 线程栈大小。如图所示,粉红色的部分就是可分配线程的内存大小,如果不显式设置-Xss或-XX:ThreadStackSize参数的时候,在Linux x64上ThreadStackSize的默认值就是1024K,也就是1MB大小,如图

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值