This article is from: http://ifeve.com/java-fork-join-framework/#more-35602
Translation sequence
Doug Lea The Great God introduced his paper on the Fork/join framework, which he wrote in Java 7.
Responsive programming (reactive PROGRAMMING/RP) as a paradigm in the entire industry is gradually recognized and landed, is the past system of business needs of the understanding of the system technology Design/Architecture Model upgrade Summary. Java as a mature platform for the trend has always been some sound acceptance and follow-up capabilities, with stunning vitality:
Java 7 provides forkjoinpool, which supports the stream provided by Java 8 (reactive stream is a core component of the RP).
Additionally, Java 8 provides LAMDA (the language component and concept of FP needed to effectively express and use RP).
With these robust but lost-time preparations in front, the RP-oriented flow APIs are provided in Java 9, providing the official RP API for the Java Circle, marking the transformation of the RP from a market-style free exploration phase to a church-style unified use.
With these instructions, you can see the fundamental importance of forkjoinpool.
By the way, another mention of Java 9 's Flow API is Doug Lee @author.
PS: Based on alex/Shanghuan translation, Fang Fei proofing text: Java Fork Join Framework, complement the "Conclusion" after 3 sections, adjusted the format and some words, organized into a complete translation. The source code in the GitHub of this warehouse, you can submit issue/fork after the submission of codes to suggest/correct.
Https://github.com/oldratlee/translations/blob/master/a-java-fork-join-framework/README.md
0. The summary
This paper describes the design, implementation, and performance of the Fork/join framework, which divides the problem into subtasks by (recursion), and then executes the subtasks in parallel, and then merges the final results in such a way that it supports parallel computing programming. The overall design refers to the work-stealing framework designed for Cilk. At the design level, the focus is on how to efficiently build and manage task queues and work threads. Performance test data show that a good parallel computing program will improve most applications, while also hinting at some potential space for ascension.
Chong 1:cilk is the Intel Cilk language. The new features of the Intel C + + editor Cilk language extension technology, adding fine-grained task support for C + + languages to add parallelism to new and existing software to make it easier to fully exploit multiprocessor capabilities.
1. Introduction
Fork/join Parallel method is one of the simplest and most effective design techniques for obtaining good parallel computing performance. The Fork/join parallel algorithm is a parallel version of the partition algorithm that we are familiar with, and the typical usage is as follows:
Result Solve (Problem Problem) {
If (problem is small) {
Directly solve problem
} else {
Split problem into independent parts
Fork new subtasks to solve each part
Join All Subtasks
Compose result from Subresults
}
}
The fork operation will start a new parallel fork/join subtask. The join operation waits until all subtasks have ended. The fork/join algorithm, like other divide-and-conquer algorithms, always recursively and repeatedly divides subtasks until these subtasks can be executed in a simple, short, sequential way.
Some of the relevant programming techniques and examples have been discussed in the "Java concurrent programming--design principles and Patterns Second Edition" [7] 4.4 chapters. This paper will discuss the design of Fjtask (section 2nd), implementation (sect. 3rd), and Performance (section 4th), which is a java™ framework that supports parallel programming. Fjtask, as part of the Util.concurrent package, can now be acquired in http://gee.cs.oswego.edu/.
2. Design
The Fork/join program can run on any framework that supports the following features: The framework enables the built subtasks to execute in parallel and has a mechanism for waiting for the subtasks to run over. However, the Java.lang.Thread class (which also includes the POSIX pthread, which is also based on Java threads) is not the optimal choice for fork/join programs:
Fork/join tasks have simple and conventional requirements for synchronization and management. The computational layout shown by the Fork/join task will lead to a more flexible scheduling strategy relative to the regular threads. For example, the Fork/join task does not need to be blocked in addition to waiting for subtasks. So the traditional cost of keeping track of blocking threads is actually a waste in this case.
For a reasonable base task granularity, the cost of building and managing a thread can be even greater than the cost of the task execution itself. Granularity, though, should be adjusted as the application runs on different platforms. But extreme coarse granularity that exceeds the thread overhead can limit parallel play.
In short, the Java Standard Threading framework is too cumbersome for fork/join programs. But since threads form the basis of many other concurrent and parallel programming, it is impossible (or impractical) to completely eliminate this cost or to adjust thread scheduling in this way.
Although the idea has been around for a long time, the first release of the system to solve these problems is cilk[5]. Cilk and other lightweight frameworks are based on the operating system's basic threading and process mechanisms to support special-purpose fork/join programs. This strategy also applies to Java, although Java threads are implemented based on the capabilities of a low-level operating system. The main advantage of creating such a lightweight implementation framework is the ability to write fork/join programs in a more intuitive way that can be run on a variety of systems that support JVMs.
Fjtask Framework is a kind of evolution based on cilk design. Other similar frameworks are hood[4], filaments[8], stackthreads[10] and some related systems that rely on lightweight execution tasks. All of these frameworks map tasks to threads in the same way that the operating system maps threads to the CPU. Only they use the simplicity, commonality, and consistency of the Fork/join program to perform this mapping. Although these frameworks are adaptable to fork/join parallel programs, they optimize the design of the:
A set of worker thread pools is ready. Each worker thread is standard ("heavyweight") to handle the thread that is stored in the queue (this is the instance object of the thread class Fjtaskrunner). Typically, the worker thread should be the same as the number of processors in the system. For some native frameworks such as Cilk, they first map to a kernel thread or a lightweight process and then run on the processor. In Java, virtual machines and operating systems need to be integrated into one another to complete the mapping of threads to processors. Then for compute-intensive operations, this mapping is a relatively simple task for the operating system. Any reasonable mapping strategy will cause the thread to map to a different processor.
All fork/join tasks are instances of lightweight execution classes, not thread instances. In Java, a stand-alone executable task must implement the Runnable interface and override the Run method. In the Fjtask framework, these tasks will inherit fjtask rather than thread as subclasses, both of which implement the Runnable interface. (for the above two cases, a class can also choose to implement the Runnable interface, where the instance object of the class can be executed either in the task or in a thread.) Because task execution is constrained by strict rules from the Fjtask method, subclasses Fjtask are relatively convenient and can be invoked directly. )
We will use a special queue and scheduling principle to manage tasks and perform tasks through worker threads. These mechanisms are implemented by the related methods provided in the task class: primarily by fork, join, Isdone (an end state identifier), and some other convenient methods, such as invoking Coinvoke to break up two or more tasks.
A simple control and management class (referred to here as Fjtaskrunnergroup) starts the work thread pool and initializes a fork/join task that is triggered by a normal thread invocation (similar to the main method in a Java program).
As a standard example for programmers to demonstrate how this framework works, this is a class that computes the Fibonacci function.
Class Fib extends Fjtask {
static final int threshold = 13;
volatile int number; Arg/result
Fib (int n) {
Number = n;
}
int Getanswer () {
if (!isdone ())
throw new IllegalStateException ();
return number;
}
public void Run () {
int n = number;
if (n <= threshold)//Granularity CTL
Number = SEQFIB (n);
else {
Fib f1 = new Fib (n-1);
Fib F2 = new Fib (n-2);
Coinvoke (F1, F2);
Number = F1.number + f2.number;
}
}
public static void Main (string[] args) {
try {
int groupsize = 2; For example
Fjtaskrunnergroup Group = new Fjtaskrunnergroup (groupsize);
Fib f = new Fib (35); For example
Group.invoke (f);
int result = F.getanswer ();
System.out.println ("Answer:" + result);
catch (Interruptedexception ex) {
}
}
int seqfib (int n) {
if (n <= 1) return n;
else return Seqfib (n−1) + SEQFIB (n−2);
}
}
This version runs at least 30 times times faster on the platform mentioned in section 4th than in the thread class for each task. While maintaining performance, the program still maintains a Java-more