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

线程池之ThreadPool与ForkJoinPool

程序员文章站 2022-07-02 16:44:31
网上对Java线程池都有很多非常具体的解析,我概念性进行总结下,如有错误,可与我联系修改。 1.1 ThreadPool Executor 一个线程池包括以下四个基本组成部分: 1、线程池管理器(ThreadPool):用于创建并管理线程池,包括 创建线程池,销毁线程池,添加新任务; 2、工作线程( ......

网上对java线程池都有很多非常具体的解析,我概念性进行总结下,如有错误,可与我联系修改。

1.1 threadpool executor

一个线程池包括以下四个基本组成部分:

  1、线程池管理器(threadpool):用于创建并管理线程池,包括 创建线程池,销毁线程池,添加新任务;

   2、工作线程(poolworker):线程池中线程,在没有任务时处于等待状态,可以循环的执行任务;

   3、任务接口(task):每个任务必须实现的接口,以供工作线程调度任务的执行,它主要规定了任务的入口,任务执行完后的收尾工作,任务的执行状态等;

   4、任务队列(taskqueue):用于存放没有处理的任务。提供一种缓冲机制。 

工作方式:

线程池有一个工作队列,队列中包含了要分配给各线程的工作。当线程空闲时,就会从队列中认领工作。由于线程资源的创建与销毁开销很大,所以threadpool允许线程的重用,减少创建与销毁的次数,提高效率。

流程图细节:

线程池之ThreadPool与ForkJoinPool

1.2 forkjoinpool executor

forkjoinpool组成类:

    1,forkjoinpool:充当fork/join框架里面的管理者,最原始的任务都要交给它才能处理。它负责控制整个fork/join有多少个workerthread,workerthread的创建,激活都是由它来掌控。它还负责workqueue队列的创建和分配,每当创建一个workerthread,它负责分配相应的workqueue。然后它把接到的活都交给workerthread去处理,它可以说是整个frok/join的容器。

    2,forkjoinworkerthread:fork/join里面真正干活的"工人",本质是一个线程。里面有一个forkjoinpool.workqueue的队列存放着它要干的活,接活之前它要向forkjoinpool注册(registerworker),拿到相应的workqueue。然后就从workqueue里面拿任务出来处理。它是依附于forkjoinpool而存活,如果forkjoinpool的销毁了,它也会跟着结束。

     3,forkjoinpool.workqueue: 双端队列就是它,它负责存储接收的任务。

     4,forkjointask:代表fork/join里面任务类型,我们一般用它的两个子类recursivetask、recursiveaction。这两个区别在于recursivetask任务是有返回值,recursiveaction没有返回值。任务的处理逻辑包括任务的切分都集中在compute()方法里面。

工作方式:

  使用一种分治算法,递归地将任务分割成更小的子任务,其中阈值可配置,然后把子任务分配给不同的线程执行并发执行,最后再把结果组合起来。该用法常见于数组与集合的运算。

由于提交的任务不一定能够递归地分割成forkjointask,且forkjointask执行时间不等长,所以forkjoinpool使用一种工作窃取的算法,允许空闲的线程“窃取”分配给另一个线程的工作。由于工作无法平均分配并执行。所以工作窃取算法能更高效地利用硬件资源。

流程图细节:

线程池之ThreadPool与ForkJoinPool

1.3 应用场景

threadpool:多见于线程并发,阻塞时延比较长的,这种线程池比较常用,一般设置的线程个数根据业务性能要求会比较多。

forkjoinpool:特点是少量线程完成大量任务,一般用于非阻塞的,能快速处理的业务,或阻塞时延比较少的。