龙空技术网

TheadPoolExecutor内部数据流转

程序员列侬 117

前言:

目前同学们对“并行计算的应用场景是什么意思”大致比较着重,我们都需要学习一些“并行计算的应用场景是什么意思”的相关资讯。那么小编同时在网络上汇集了一些有关“并行计算的应用场景是什么意思””的相关知识,希望兄弟们能喜欢,兄弟们快快来学习一下吧!

ThreadPoolExecutor是什么

使用 ThreadPoolExecutor 的主要原因是它可以提高程序的效率和性能。它通过维护一个线程池来处理任务,可以避免频繁地创建和销毁线程,这样可以减少线程切换的开销。此外,它还可以限制线程的数量,避免系统资源过度消耗,并在必要时自动调整线程数量。

使用 ThreadPoolExecutor 还可以提高程序的可维护性。它可以方便地管理线程,跟踪线程状态,并在必要时取消和终止线程。这可以减少程序的复杂性,并使代码更易于维护。

总之,使用 ThreadPoolExecutor 可以提高程序的效率和性能,并提高程序的可维护性。

网上已有很多关于ThreadPoolExecutor原理解析的文章,本文主要是从一个例子来说明内部的数据流转

ThreadPoolExecutor在类中的继承关系如下图

ThreadPoolExecutor内部的状态和工作线程数计算过程

由一个32的整形来表示状态和线程数量,其中高3位是状态,第29位是线程数据量,即线程数量的理论值是(2^31)-1,这里和ReentrantReadWriteLock表示的读写锁类似。这样可以节省内存空间,并且可以提高程序的性能。

private static final intCOUNT_BITS= Integer.SIZE- 3;00100000 00000000 00000000 00000000-                                                               1---------------------------------------------00011111 11111111 11111111 11111111private static final int COUNT_MASK= (1 <<COUNT_BITS) - 1;负数以其正值的补码形式表达。原码 00000000 00000000 00000000 00000001反码:将二进制数按位取反     11111111 11111111 11111111 11111110补码:反码加1称为补码。     11111111 11111111 11111111 11111111 再左移29位:11100000 00000000 00000000 00000000  (1)如果补码的符号位为“0”,表示是一个正数,所以补码就是该数的原码。 (2)如果补码的符号位为“1”,表示是一个负数,求原码的操作可以是:符号位为1,其余各位取反,然后再整个数加1。10011111 11111111 11111111 11111111+                                 1----------------------------------- 10100000 00000000 00000000 00000000转换为10进制-536870912private static final int RUNNING= -1 <<COUNT_BITS;private static final int SHUTDOWN=  0 <<COUNT_BITS;1左移29位 100000000000000000000000000000  536870912privatestatic final intSTOP=  1 <<COUNT_BITS;10左移29位 1000000000000000000000000000000  1073741824private static final intTIDYING=  2 <<COUNT_BITS;11左移29位1左移29位 1100000000000000000000000000000  1610612736private static final intTERMINATED=  3 <<COUNT_BITS;    00011111 11111111 11111111 11111111~ 11100000 00000000 00000000 00000000& 10100000 00000000 00000000 00000000------------------------------------------------    10100000 00000000 00000000 00000000private static int runStateOf(int c)     { return c & ~COUNT_MASK; }  10100000 00000000 00000000 00000000&00011111 11111111 11111111 11111111-----------------------------------------------  00000000 00000000 00000000 00000000private static int workerCountOf(int c)  { return c & COUNT_MASK; }10100000 00000000 00000000 0000000000000000 00000000 00000000 00000000---------------------------------------------- 10100000 00000000 00000000 00000000  private static int ctlOf(int rs, int wc) { return rs | wc; }

内部状态流转

ThreadPoolExecutor有五个状态,掌握了状态的流转就能更好的理解内部工作原理

以一个例子来说明内部的是如何流转的

下面图用来说明向线程池里面提交任务时内部的数据流转,什么时候开启线程,什么时候加入队列的。注意这里任务的执行时间比较长。如果任务需要执行的时间段的话,情况会有差异。内部的线程是在addWorker时通过构造函数创建getThreadFactory().newThread(this);

当线程获取不到任务时,非核心线程会被JVM回收,核心线程是否被销毁由allowCoreThreadTimeOut控制。

使用场景

并行计算: 使用 ThreadPoolExecutor 可以提高程序的并行能力,提高计算速度。异步 I/O: 使用 ThreadPoolExecutor 可以并行处理 I/O 操作,从而提高程序的吞吐量。任务调度: 使用 ThreadPoolExecutor 可以实现定时任务、周期性任务和延迟任务。网络服务器: 使用 ThreadPoolExecutor 可以并行处理客户端请求,从而提高网络服务器的吞吐量。数据库连接池: 使用 ThreadPoolExecutor 可以管理数据库连接,避免频繁创建和销毁连接。

总之, 如果你的程序需要并发执行多个任务,使用 ThreadPoolExecutor 就是一个很好的选择。

标签: #并行计算的应用场景是什么意思