当前位置: 移动技术网 > IT编程>开发语言>Java > 线程池之ThreadPool与ForkJoinPool

线程池之ThreadPool与ForkJoinPool

2019年03月22日  | 移动技术网IT编程  | 我要评论

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

1.1 threadpool executor

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

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

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

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

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

工作方式:

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

流程图细节:

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使用一种工作窃取的算法,允许空闲的线程“窃取”分配给另一个线程的工作。由于工作无法平均分配并执行。所以工作窃取算法能更高效地利用硬件资源。

流程图细节:

1.3 应用场景

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

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

 

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网