Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to analyze Fork/Join concurrency Framework of Java

2025-02-23 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

This article will explain in detail how to analyze the Fork/Join concurrency framework of Java. The content of the article is of high quality, so the editor shares it for you as a reference. I hope you will have some understanding of the relevant knowledge after reading this article.

Today I will record some superficial understanding of Fork/Join.

1. What is Fork/Join?

The official definition of Oracle is that the Fork/Join framework is a multithreaded processor that implements the ExecutorService interface. It can divide a large task into several small tasks to execute concurrently, make full use of available resources, and then improve the execution efficiency of the application.

Fork/Join implements ExecutorService, so its tasks also need to be executed in a thread pool. The difference is that it uses a work theft algorithm, and idle threads can steal tasks from fully loaded threads to help execute them. My personal understanding of job theft is that because each thread in the thread pool has a queue, and threads do not affect each other. Then the thread gets a task from the head of its own task queue to execute each time. If at some point the task queue of one thread is empty and there are still tasks in the task queue of the other threads, the thread will take a task from the task queue of other threads to help execute it. It's like stealing other people's jobs)

The core of the Fork/Join framework is the ForkJoinPool class that inherits AbstractExecutorService, which ensures the normal operation of the work theft algorithm and ForkJoinTask.

2. The basic usage of Fork/Join

(1) Fork/Join base class

As mentioned above, Fork/Join is to divide a large task into several small tasks, so the * step is to split the task, roughly as follows:

If (this task is small enough) {execute the task to be done} else {split the task into two small parts and wait for the execution result}

To implement FrokJoinTask, we need a base class that inherits RecursiveTask or RecursiveAction and puts the above code into the coupute method of the base class according to its own business situation. Both RecursiveTask and RecursiveAction inherit FrokJoinTask, and the difference between them is that RecursiveTask has a return value while RecursiveAction does not. Here is a Demo that I did to select an element with "a" in the list of strings:

@ Override protected List compute () {/ / when the difference between end and start is less than the threshold, start the actual filtering of if (end-this.start)

< threshold) { List temp = list.subList(this.start, end); return temp.parallelStream().filter(s ->

S.contains ("a")) .tasks (Collectors.toList ());} else {/ / if the difference between end and start is greater than the threshold, / / decompose the large task into two small tasks. Int middle = (this.start + end) / 2; ForkJoinTest left = new ForkJoinTest (list, this.start, middle, threshold); ForkJoinTest right = new ForkJoinTest (list, middle, end, threshold); / / parallel execution of two "small tasks" left.fork (); right.fork () / / combine the results of the two "small tasks" List join = left.join (); join.addAll (right.join ()); return join;}}

(2) Executive class

Once the base class is ready to call, we first need the Fork/ join thread pool ForkJoinPool, and then submit a ForkJoinTask to the thread pool and get the result. The input parameter of ForkJoinPool's submit method is a ForkJoinTask, and the return value is also a ForkJoinTask, which provides a get method to get the execution result.

The code is as follows:

ForkJoinPool pool = new ForkJoinPool (); / / submit decomposable ForkJoinTask tasks ForkJoinTask future = pool.submit (forkJoinService); System.out.println (future.get ()); / / close thread pool pool.shutdown ()

In this way, we have completed a simple Fork/Join development.

Tip: Fork/Join is also used in the parallelSort () method of java.util.Arrays in Java8 and the method encapsulated in the java.util.streams package. (careful readers may notice that I also use stream in Fork/Join, so this Fork/Join is actually superfluous, because stream has already implemented Fork/Join, but this is only a Demo presentation, so it doesn't matter if it doesn't have any practical use.)

Complete code is attached for future reference:

1. Define an abstract class (for extension, there is no practical use in this example, and this class may not be defined):

Import java.util.concurrent.RecursiveTask; / * Description: ForkJoin interface * Designer: jack * Date: 2017-8-3 * Version: 1.0.0 * / public abstract class ForkJoinService extends RecursiveTask {@ Override protected abstract T compute ();}

two。 Define the base class

Import java.util.List; import java.util.stream.Collectors; / * Description: ForkJoin base class * Designer: jack * Date: 2017-8-3 * Version: 1.0.0 * / public class ForkJoinTest extends ForkJoinService {private static ForkJoinTest forkJoinTest; private int threshold; / / threshold private List list; / / List private ForkJoinTest to be split (List list, int threshold) {this.list = list; this.threshold = threshold } @ Override protected List compute () {/ / when the difference between end and start is less than the threshold, start the actual filtering of if (list.size ()

< threshold) { return list.parallelStream().filter(s ->

S.contains ("a")) .tasks (Collectors.toList ());} else {/ / if the difference between end and start is greater than the threshold, break down the large task into two small tasks. Int middle = list.size () / 2; List leftList = list.subList (0, middle); List rightList = list.subList (middle, list.size ()); ForkJoinTest left = new ForkJoinTest (leftList, threshold); ForkJoinTest right = new ForkJoinTest (rightList, threshold); / / execute two "small tasks" left.fork () in parallel; right.fork () / / combine the results of two "small tasks" List join = left.join (); join.addAll (right.join ()); return join }} / * get ForkJoinTest instance * @ param list pending List * @ param threshold threshold * @ return ForkJoinTest instance * / public static ForkJoinService getInstance (List list Int threshold) {if (forkJoinTest = = null) {synchronized (ForkJoinTest.class) {if (forkJoinTest = = null) {forkJoinTest = new ForkJoinTest (list, threshold) } return forkJoinTest;}}

3. Executive class

Import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.concurrent.ExecutionException; import java.util.concurrent.ForkJoinPool; import java.util.concurrent.ForkJoinTask / * Description: Fork/Join execution class * Designer: jack * Date: 2017-8-3 * Version: 1.0.0 * / public class Test {public static void main (String args []) throws ExecutionException, InterruptedException {String [] strings = {"a", "ah", "b", "ba", "ab", "ac", "sd", "fd", "ar", "te", "se", "te" "sdr", "gdf", "df", "fg", "gh", "oa", "ah", "qwe", "re", "ty", "ui"} List stringList = new ArrayList (Arrays.asList (strings)); ForkJoinPool pool = new ForkJoinPool (); ForkJoinService forkJoinService = ForkJoinTest.getInstance (stringList, 20); / / submit decomposable ForkJoinTask tasks ForkJoinTask future = pool.submit (forkJoinService); System.out.println (future.get ()); / / close thread pool pool.shutdown () }} on how to analyze Java Fork/Join concurrency framework to share here, I hope that the above content can be of some help to you, can learn more knowledge. If you think the article is good, you can share it for more people to see.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report