When the hardware processing power can not be vertically developed according to Moore's law, the choice of horizontal development, multi-core processor has been widely used. The future with the further development of technology, there may be hundreds of processing cores, but the existing programs run on multi-core processors do not get a greater performance improvement, the main bottleneck is that the program itself is not strong concurrent processing capacity, can not reasonably use multi-core resources. The existing processing scheme is to start from the software, trying to use multi-threading, is the program at the same time to support the calculation of multiple tasks, this multi-threaded processing scheme in the case of a small number of processors can significantly improve application performance, but we are more favored by the hardware implementation of multithreaded processing mode, But there is no good result in this area yet.
Forkjoin is a native multi-threaded parallel processing framework provided by JAVA7, whose basic idea is to divide the big man into small tasks and finally converge the small tasks to get results. It is very similar to the MapReduce framework provided by Hadoop, but the task of MapReduce can take full advantage of the ability of the cluster to complete computing tasks for all compute nodes within the cluster. Forkjoin is more akin to a standalone version of MapReduce.
Even if it is not through MapReduce, only the application itself can be decomposed and synthesized tasks, but from the implementation of the difficulty to consider, their own implementation may bring greater complexity, so programmers need a paradigm to deal with this kind of task. The actor-model-based framework, such as Akka, is already in the process of multi-threading, while the Forkjoin is for implementations that have a noticeable need for task-splitting features. The scenario is that if an application can be decomposed into multiple subtasks, and the result of combining multiple sub-tasks can get the final answer, it is appropriate to use the fork/join pattern. Fork/join use two classes to accomplish both of these things: · Forkjointask: To use the Forkjoin framework, you must first create a forkjoin task. It provides an operational mechanism for executing fork () and join in a task, and usually we do not inherit the Forkjointask class directly, only to inherit its subclasses directly.1. Recursiveaction, for tasks that do not return results 2. Recursivetask, for tasks with return values
· Forkjoinpool:task to execute through Forkjoinpool, the split subtasks are added to the current worker thread's double-ended queue and into the queue's head. When there is no task in a worker thread, a task is fetched from the end of the queue of other worker threads. The Forkjoin Framework uses the idea of work-stealing (work-stealing), which steals tasks from other queues to execute, with a workflow diagram of:
This algorithm reduces thread waits and competition. Here's an example:
Packagecom.inspur.jiyq.forkjoin.sum;ImportJava.util.concurrent.ForkJoinPool;Importjava.util.concurrent.Future;ImportJava.util.concurrent.RecursiveTask; Public classCounttaskextendsRecursivetask<integer>{ Private Static Final LongSerialversionuid = -3611254198265061729l; Public Static Final intThreshold = 2; Private intstart; Private intend; PublicCounttask (intStartintend) { This. Start =start; This. end =end; } @OverrideprotectedInteger Compute () {intsum = 0; //Calculate tasks If the task is small enough BooleanCancompute = (End-start) <=threshold; if(cancompute) { for(intI=start; i<=end; i++) {sum+=i; } } Else { //if the task is greater than the threshold, it is split into two sub-task calculations intMiddle = (start + end)/2; Counttask Lefttask=Newcounttask (start, middle); Counttask Righttask=NewCounttask (middle+1, end); //To perform sub-taskslefttask.fork (); Righttask.fork (); //wait for task execution to finish merging its results intLeftresult =Lefttask.join (); intRightresult =Righttask.join (); //To Merge sub-taskssum = Leftresult +Rightresult; } returnsum; } Public Static voidMain (string[] args) {Forkjoinpool Forkjoinpool=NewForkjoinpool (); //generate a calculation task, calculate 1+2+3+4Counttask task =NewCounttask (1, 100); //Perform a taskfuture<integer> result =Forkjoinpool.submit (Task); Try{System.out.println (Result.get ()); } Catch(Exception e) {System.out.println (e); } }}
Requirements such as summation and sequencing can be achieved through forkjoin thinking, but in practice it is necessary to perform the required performance tests to confirm the magnitude of the performance increase. In the above code, you define an additive task, in the compute method, to determine whether the current value is less than a threshold value, if it is calculated, if it is not, continue splitting, and merge the intermediate result of the subtask. After the task definition executes the task, Fork/join provides an extension thread for the executor framework to perform the task. Reference: http://blog.csdn.net/lubeijing2008xu/article/details/18036931 http://www.iteye.com/topic/643724
The forkjoin of Java Parallel Framework Learning