问题描述
- 使用多个线程池还是一个线程池
-
最近在技术理论上遇到一个问题,不知道怎么解决。
问题描述:我们交易平台有4个商品(A、B、C、D)需要进行现在交易,交易的核心方法dealorder是
一个加了锁和事务的方法,而且该类是针对每一个商品的,即最多同时可以执行4个dealOrder方法,即每个商品执行一个该方法。@Transactional public synchronized Message dealOrder()
CPU核心数是固定的,假如为6核心,目前就存在一个问题,
情况1:假如说创建一个线程池,过来了大量的A商品请求,超过6个就被放进了队列中,再过来B、C、D商品的请求,也无法再进行处理。
情况2:假如说创建6个线程池,每个商品一个线程池,这时候,理论上ABCD四个商品就会在各自的线程池中进行处理,这样就不会发上1情况的其他商品等待资源释放的问题,但是真实情况下,6个线程池会去抢占一个CPU获得处理还是自动获取6个CPU核心数进行处理.
我现在没有理论上的经验,通过实践似乎可以看出来2情况要理想,但是真实情况下是否如此,真心需要理论上给出结论。
解决方案
一个,你创建那么多,也不可能都在运行,系统会调度的
解决方案二:
非常感谢你的回答,我一直没有弄清楚CPU核心数和4个线程池(每个里面一个线程),和一个线程池(里面4个线程)之间的关系,只是情况2解决了
大量A商品(A1A2A3A4A5A6、B1B2)这中请求的时候,B1不需要等待A1A2处理完后再进入线程池,而会直接进入到B商品的线程池进行处理,但是
我一直怀疑真实情况下,CPU在处理1个线程池(多个线程),多个线程池(1个线程)之间的内存分配和CPU调度之间的关系,非常迫切希望您能多聊聊一些知识。
解决方案三:
多个线程池跟一个线程池有啥区别,处理是在线程中跑 ,当然估计 你的自己写线程池 ,在里面重新定义原子操作 系统的估计不咋好使
解决方案四:
如果A,B,C,D本身就没什么区别,都是作为一个处理对象,那么开一个线程池,里面放CPU个数*2,这么多线程,这样可以比较最大化利用线程池和CPU的能力。
解决方案五:
CPU的核数与线程数和线程池数没有必然关系。.net本身就为应用程序分配了一个线程池,我们常用的方法的异步调用就是将调用的.net应用程序线程池来跑的。
之所以我们自己要创建线程池,是因为一类的操作要访问一些资源,而这些资源在切换的时候比较消耗时间,所以把这一类操作给一种线程池来处理,这样更快。
CPU的核数属于系统资源,它的分配是由操作系统按照一定的算法按时间片分配的。不会让应用程序来控制,不然,你一个线程池的几个线程老占着一个核不放,它在很闲的时候,这个核岂不废了。
一但一个线程启动了,他就等于把它交给操作系统了。至于要给哪个核处理,应用程序是管不了的,我们只需要在应用程序中做好资源访问的控制,线程的等待等操作就行了。
解决方案六:
线程池的设计,也要因地制宜。
我觉得你的这个问题,如果ABCD的数量不多,一个线程或者就利用系统的线程池就可以了。
如果处理总数很频繁,ABCD谁多谁少不确定,并且ABCD都要操作一个资源(例如某数据表:Cargo),一个线程池就够了。
这个时候,你还得自己给线程池写线程的调度算法。
如果每个类中的消息都很多频繁,且每种商品都会操作一种资源(例如每种商品都有一张数据表),这个时候可以为每个商品弄一个线程池。