关于多线程、高并发的一次探索

最近在开发一个接口,接收任务、数据库处理,并返回处理结果。倒腾完功能后,一如既往地进行性能提升。

这里的主要思路是,通过测试找到系统到达最大吞吐量时(其实是数据库吞吐量),对应的线程并发数。然后限制线程的最高并发数。以让系统的性能达到最优。我把吞吐分两种,程序的吞吐(与cpu,内存,网络等资源相关)和数据库的吞吐。系统吞吐量则是由这两种吞吐中较弱的决定。我这个案例中,由数据库吞吐量决定。

举个例子,通过测试发现,并发线程为15时,系统平均每秒钟处理的任务最多(吞吐量最大)。则将系统的最大并发数限制为15.系统就会以最佳的状态运行。

猜测最佳并发数是10左右,那先10个线程并发,测10个任务看看。

 

以上是每个任务耗时,1268ms完成了所有任务。所以,每秒吞吐量tps=10/1.271=7.88

.....继续测>10和<10的并发数,最后得出结果:10个线程并发,吞吐量最大。

 

接下来进行最大线程数的限制,由于lz使用java语言,java提供了方便快捷的并发编程工具ExecutorService,这个随便搜一下就很多介绍。java6以上可用。

使用时注意 ExecutorService的十个使用技巧

此时系统已经能够确保同时进行数据库操作的任务最多只有10个。剩下的排队吧。

排队引入了一个问题,有些任务会排很久才能得到处理。而接口的要求是1秒内必须返回。怎么办?只能使用异步了,java提供了辅助并发编程的工具CountDownLatch。

于是我在程序里加了一行代码 latch.await(1000,TimeUnit.MILLISECONDS); 意思是,我等你1000ms,你做完了告诉我,我接着做下面的事。1000ms后没做完,我也接着做下面的事。问题解决了。附上一些并发编程工具类的资料 Java并发编程

 

还差一步,ExecutorService会对超出的任务数进行拒绝,所以为了让所有进入系统的任务都得到执行,还得限制进入的任务数。

java又提供了另一个辅助并发编程的工具Semaphore,信号量。执行任务前,先判断position.availablePermits()>0?,意思是,是否还有许可去执行这个任务,若有,则执行,完了释放许可。若没有,则等待许可。我等待许可的代码是:Thread.sleep(1500);再判断 position.availablePermits(),1500ms是我的任务的大概执行时间。你也可以不sleep,直接不停地进行判断,这个判断不会耗很多资源。

 

到这里,系统的性能优化就完了。准确地说,是前端程序的优化,不包括数据库处理的优化。

 

题外话,这是lz第一次尝试写博客。博客中有错误的话,欢迎大家指出,感谢csdn这个平台提供资源让我们进步!

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值