欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

更快的线程池??

程序员文章站 2022-01-22 10:05:07
...

 

提起线程池我们会想到两件事:

1.线程池是为了复用线程避免重复开辟线程带来开销.

2.我们用多线程是为了提升执行效率,但是多线程会带来数据同步问题.加锁会降低性能,线程上下文切换也会降低性能.

 

我在想一个问题:能不能避免加锁和避免上下文切换带来的性能开销?如果能避免这个开销,多线程最后一个被诟病的问题岂不是解决了?

 

在此之前,我想说这个解决办法并不是用多个线程池组去管理你的业务.例如你可能会用登录线程池去处理登录逻辑,注册线程池去处理注册逻辑.用这种方法达到业务隔离,

 

但是本文并不是在这个层面上去做的事情,而是细分到单个线程池如何去管理这个线程池的线程分配的问题.

 

假设你的线程池的线程数量为4,那么你会有A B C D 4个线程,需要去执行1万个任务.按照目前普通的线程池做法其实就是随机在A B C D上分配任务并且去执行.正是这种随机性导致并发问题和上下文切换的开销.

 

假设每次执行任务恰好都是随机的那么会有 A B C D 4个线程4倍开销,现在假设任务能分配到根据分组,某一组的任务能集中分配到A B C D的某一个线程上,那么就会把这个开销降低4倍.

如果线程池有100个线程那么会降低100倍,因为之前每个任务都随机分配在不同线程就会有不同线程去竞争这些任务带来开销,线程经过排队避免了这种开销.

 

有什么应用场景?

 

就算是针对某单个线程池,假设线程数量为4个,其实我们执行的任务大部分并不是没有规律的,可以根据用户/房间号进行分组.

例如你在做某个棋牌游戏,假设有1万个房间,每个房间都会有一个定时器去做回调处理.通常我们会用一个线程池去处理这一万个房间里面的计时任务.但是因为是线程池执行任务是根据队列顺序的也是随机的所以会带来开销.

那么我们可以根据房间号去分组,这样能让同一个房间号能分配在某个线程去执行,

即用到了多线程的好处:4个线程处理了1万个任务,又避免了线程的一些开销.不需要加锁,没有竞争没有上下文切换.

 

***********************************************************

由于工作繁忙还没完全实现并测试性能提升多少的问题.

 

做法是

1:每个任务多一个分组属性.

public class GroupRunable implements Runnable {

 private Object group;

 

2:改造ThreadPoolExecutor的BlockingQueue<Runnable> workQueue 变成一个Map每个Group 一个Queue

 

改造getTask()方法,如果某个Task在某个Thread上执行了,就把后面的这个Group的Task都分配到这个Thread去执行.

 

 

待续........