本文将介绍用多线程解决数据传输效率的问题,在很多大数据场景中要求我们对于数据采集的时候达到实时或者准实时,这也同时要求了对接的源数据库的数据是实时与准实时的,在程序运行时不过于占用内存资源的情况下,多线程是用来提高数据传输效率的重要手段之一。
1.线程与多线程
什么是线程?
线程是程序中的一个执行流,每个线程都有自己的专有寄存器(栈指针、程序计数器等),但代码区是共享的,即不同的线程可以执行同样的函数。
因为线程的这个特性,也让多线程场景得以实现。
什么是多线程?
多线程是指程序中包含多个执行流,即在一个程序中可以同时运行多个不同的线程来执行不同的任务,也就是说允许单个程序创建多个并行执行的线程来完成各自的任务。
多线程图解
多线程的好处是可以提高cpu的利用率,在单线程场景中,程序运行时cpu对于该程序处理的计算状态只有运行、停止两种情况,而在多线程场景中cpu对于不同的线程可以有不同状态,例如有的线程是停止的状态时,cpu还在处理计算正在运行的线程。
为了提高效率是不是线程数越多越好?
线程能否提升效率和计算的过程与所运行的任务程序是否是CPU密集型还是IO密集型有关,如果是CPU密集型的任务,线程数过多只会降低效率,如果是IO密集型的,可以多设置一些线程池中线程的数量,这样就能让在等待IO的这段时间内,线程可以去做其它事,提高并发处理效率。就好像一个工厂,增加生产线并配置适当数量的工人才能提升生产效率,只是不断增加工人生产效率反而会越来越低...
2.实际开发中多线程线程数的确定
制约线程池大小的因素是什么?
cpu核心数目的限制:
如果是CPU密集型应用,则线程池大小设置为N+1
如果是IO密集型应用,则线程池大小设置为2N+1(因为io读数据或者缓存的时候,线程等待,此时如果多开线程,能有效提高cpu利用率)
如果一台服务器上只部署这一个应用并且只有这一个线程池,那么这种估算或许合理,具体还需自行测试验证。
但是,IO优化中,这样的估算公式可能更适合:
最佳线程数目 = ((线程等待时间+线程CPU时间)/线程CPU时间 )* CPU数目
因为很显然,线程等待时间所占比例越高,需要越多线程。线程CPU时间所占比例越高,需要越少线程。
下面举个例子:
比如平均每个线程CPU运行时间为0.5s,而线程等待时间(非CPU运行时间,比如IO)为1.5s,CPU核心数为8,那么根据上面这个公式估算得到:((0.5+1.5)/0.5)*8=32。这个公式进一步转化为:
最佳线程数目 = (线程等待时间与线程CPU时间之比 + 1)* CPU数目
对接程序或者第三方接口对于线程数量的限制:
在实际场景中,有很多数据是要从其他程序或者第三方接口获取,这样就收到其他程序与第三方接口的制约,而且合作的接口不同,对于线程数的制约是不同的,有的接口支持上百个线程的程序对接,有的接口仅支持几个、十几个线程对接。
3.实际开发中多线程线的应用
在实际开发过程中使用多线程会遇到几个比较棘手的问题,例如场景是对接接口的时候需要传入接口所需的必要字段数据,循环调用接口。
问题一:获取大量接口所需字段数据调用多线程,会出现每一个线程将所有字段数据循环一遍的问题。
解决办法:需要将大量的字段数据进行拆分,有多少个线程就拆分成多少的分区
问题二:数据拆分之后调用多线程,会出现每个数据分区都会去调用多线程的情况。
解决办法:将数据拆分与线程设置结合起来,达到每一个数据分区对应每一个线程。
获取对接接口必要字段数据与数据量,设置线程数量,按照线程数量对数据进行拆分,如果线程数量大于字段数据量,设置字段数据量为线程数量,将拆分后的字段数据分给每一个线程去循环执行代码逻辑。如果之后有性能再次提升的需求,只需要改变线程数量即可。
4.总结
本文简单的介绍了多线程的概念,以及在数据传输优化的简单场景,在实际的测试中服务器的cpu利用率有一个较大的提升,并且数据传输的性能提高了线程的倍数(16倍),以上就是本文的全部内容,如有误,欢迎指正留言