当前位置: 首页 > 网络应用技术

[高度并发]什么是forkjoin?足以阅读本文!

时间:2023-03-05 22:12:35 网络应用技术

  摘要:ForkJoin将复杂的计算作为一项任务,并且分解的多个计算是作为子女任务并行执行的。

  在JDK中,它提供了这样的函数:它可以将复杂的逻辑分为简单的逻辑以执行并行执行,并且在每个并行执行完成后,请执行数据。

  ForkJoin是JDK1.7提供的多线程并发处理框架。ForkJoin框架的基本思想是统治它。什么是分裂的?该部门是根据设定的阈值分解为多个计算的复杂计算,然后总结每个计算结果。相应地,ForkJoin将复杂的计算作为任务,并且分解的多次计算是作为子女任务并行执行的。

  对于Java语言,它天生是为了支持多线程并发编程,该编程也在并发编程领域中开发。Java在开发过程中对并发编程的支持刚刚证实了这一点。

  并行性基本不同。

  并发性同时指的是,只有一个线程可以获得CPU执行任务,并且多个线程很快执行,这使得在宏中同时效果多个线程。并发图可以由以下来表示数字。

  并行行走是指何时在多个CPU的核心同时执行多个线程,这些线程是同时实现的。

  一个大尺度的问题分为小规模的子问题,然后分为其中。最后,合并问题的解决方案可以通过原始问题来解决。

  ①将原始问题分开;

  ②寻求解决孩子的问题;

  ③合并问题的解决方案是原始问题的解决方案。

  我们可以使用以下伪代码来表示此步骤。

  在治疗的划分中,子问题通常彼此独立。因此,他们经常找到解决问题的算法。

  Java 1.7引入了一个新的并发框架-Fork/Join框架,该框架主要用于实现“分区和规则”算法,尤其是在除法后递归调用的函数。

  ForkJoin框架的本质是并行执行任务的框架。它可以将大型任务分为几个小任务。最后,大型任务的结果是在每个小任务的结果之后获得的。在Java中,Forkjoin框架与ThreadPool共存,而不是替换ThreadPool。

  实际上,Java 8中引入的并行流量计算是为Forkjoinpool实施的。例如,在并行流中使用并行流量打印数字组的过程。

  该代码后面使用了forkjoinpool。

  说到哪个,读者可能会问:您可以使用线程池中的ThreadPoolExecutor来实现它吗?为什么要使用forkjoinpool?forkjoinpool是什么样的幽灵?InterSectionNext,我们会回答这个问题。

  ForkJoin框架是JDK1.7引入的一项新功能。像ThreadPoolExecutor一样,它还实现了执行程序和执行人员服务界面。如果传递到构造函数中指定函数的线程数,则将当前计算机可用的CPU设置为线程。数量是默认值。

  forkjoinpool主要使用** divide -conforithmm来解决问题。典型的应用程序,例如快速排序算法。这里的重点是,forkjoinpool可以使用相对较少的线程来处理大量任务。

  例如,要对1000万个数据进行排序,那么此任务将分为两种500万组的500万个分类任务,并为这两组500万个数据进行合并任务。基于此类型,将对500万个数据进行相同的细分处理处理。最后,将设置一个阈值,以指出当达到数据量表时,将停止此划分处理。

  例如,当元素数量少于10时,将停止分割,并且插入排序将用于对它们进行排序。最后,所有任务将添加约200万+。关键是要进行任务。,只有在所有子任务完成后才可以执行。

  因此,当使用threadPoolExecutor时,分区方法存在问题,因为ThreadPoolExecutor中的线程无法在任务队列中添加另一个任务并在等待任务完成后继续执行。并且使用ForkJoinPool可以解决此问题,它可以允许该问题线程以创建新任务并挂起当前任务。目前,线程可以选择从队列执行的子任务。

  那么,ThreadPoolExecutor或Forkjoinpool的性能有什么区别?

  首先,使用forkjoinpool可以使用有限数量的线程来完成许多具有父母关系的任务,例如使用4个线程完成超过200万任务。但是,当使用ThreadPoolExecutor时,无法完成,因为线程是线程在ThreadPoolExecutor中,不能选择执行子任务的优先执行。当您需要通过父亲关系关系完成200万个任务时,还需要200万个线程。显然这很不舒服。这也是非常不合理的!交叉路口

  如果我们需要执行相对较大的任务,我们可以将此任务分为几个非依赖性子任务。为了减少线程之间的竞争,这些子任务被放入不同的队列中,对于每个queuecreate,一个单独的线程以在队列中执行任务。线程和队列对应于一个-to -One对应。其他线程,因此将其窃取其他线程的队列以窃取任务以执行。通常使用末端队列。窃取任务的线程将始终从两个末端队列的尾部执行任务。

  窃取算法的工作优势:充分利用线程进行并行计算,并减少线程之间的竞争。

  窃取算法的工作缺点:在某些情况下,仍有竞争,例如两个末端队列中的一个任务。该算法会消耗更多的系统资源,例如创建多个线程和多个两个终端队列。

  叉/联接框架限制:

  对于叉/联接框架,当任务正在等待子任务使用联接操作创建时,执行此任务的工作线程是找到其他难忘的任务并启动这些难忘的任务。为了实现此目标,叉子/联接框架的任务有一定的局限性,以提高应用程序的运行时间。

  (1)该任务只能用于与叉子和加入操作的同步机制。如果使用其他同步机制,则不能在同步过程中执行其他任务。例如,在叉/联接框架中,任务是睡觉的,因此在睡眠期间,此任务的工作线程将无法执行其他任务。(2)(2)在叉/联接框架中,拆分任务不应执行IO操作,例如:读取和编写数据文件。(3)不能抛出任务以检查异常,并且必须通过必要的代码造成这些异常。

  叉期框架中的一些重要类如下所示。

  下面显示了forkjoinpool框架中涉及的主要类。

  1.Forkjoinpool类

  实现了ForkJoin框架中的线程池。从类图可以看出,forkjoinpool类实现了线程池的执行器接口。

  我们还可以在下图中看到forkjoinpool的类图。

  其中,您可以使用opecutor.newworkstealpool()方法来创建forkjoinpool。

  Forkjoinpool提供了以下提交任务的方法。

  2.ForkJoinworkerThread类

  在ForkJoin框架中实现线程。

  3.ForkJointask类

  forkjointask封装了数据及其相应的计算,并支持良好的数据并行。ForkJointask比线更轻,而Forkjoinpool中的少量工作线程可以运行很多forkjointask。

  forkjointask类主要包括两个方法fork()和join(),以实现任务的旋转和合并。

  fork()方法类似于thread.start(),但是它不会立即执行任务,而是将任务放入工作queue.unlike thread.join()方法,forkjointask的join()方法不是一个简单的阻塞线程,但使用工作线程来运行其他任务。当工作线程称为join()时,它将处理其他任务,直到您注意到已完成目标任务为止。

  我们可以使用以下图来表示此过程。

  forkjointask有3个子类:

  4.rcursivetask类

  带有返回结果的forkjointask实现可召唤。

  5. rcursiveaction类

  forkjointask没有返回结果实现可运行的。

  6.CountedCompleter类

  任务完成后,它将触发自定义钩函数的执行。

  本文分享了华为的真诚云社区,作者:宾赫。