Fork-join Frame
The fork operation is to divide a large problem into several smaller problems. In this partitioning process is generally recursive. Until the calculation can be done directly. The size of the sub-problem needs to be properly selected. Too large a sub-problem is not conducive to improving performance in parallel, while too small sub-problems can have a significant additional overhead. After each sub-problem calculation is complete, you can get a partial solution to the whole problem. The function of join operation is to organize these decomposed mobile phones and get the complete solution.
In the Fork/join framework, a sub-problem cannot continue to execute because it waits for the completion of another sub-problem. The thread that handles the sub-problem is actively looking for other sub-issues that have not yet run to complete. This approach reduces the wait time for threads and improves performance. You should avoid using synchronized keywords or other ways of synchronizing in sub-problems. Nor should it be a blocking IO or excessive access to shared variables. Ideally, the implementation of each sub-problem should only be CPU-dependent, and only for the internal objects of each problem. The only synchronization should occur between the child problem and the parent problem that created it.
Main classes of the Fork/join framework
A task under a Fork/join framework is represented by the Forkjointask class. Forkjointask implements the future interface, which can be used in the way of the future interface. The important two methods in the Forkjointask class are fork and join. The fork method initiates the execution of a task in one way, while the join method waits for the task to complete and returns a pointer to the result. In creating your own task, it is best not to inherit from the Forkjointask class directly, but to inherit from the subclass Recurisivetask or Recurisiveaction class of the Forkjointask class. The difference between the two is that the tasks represented by the Recurisivetask class can return results, and the Recurisiveaction class does not.
Fork/join the execution of a framework task is performed by an object of the Forkjointask class, you can also use the generic callable and runnable interfaces to represent the task. The tasks performed in the objects of the Forkjoinpool class can be divided into two categories, one for the task submitted by execute, invoke, or submit, and a sub-task that is generated by the object of the Forkjointask class during execution and is run by the fork method. The general practice is to represent the entire problem of an object of the Forkjointask class with the first type being committed, while the subtasks generated during execution do not need to be processed, and the Forkjoinpool class object is responsible for the execution of the child task.
Forkjoinpool is an implementation class for Executorservice and is therefore a special thread pool. The use method is similar to the executor framework. Forkjoinpool provides the following two commonly used constructors:
Forkjoinpool (int parallelism) creates a forkjoinpool that contains parallelism parallel threads.
Forkjoinpool () creates forkjoinpool with the return value of the Runtime.availableprocessors () method as the parallelism parameter.
Forkjoinpool has the following three ways to start a thread:
Use Forkjoinpool's Submit (Forkjointask Task) or invoke (Forkjointask Task) method to perform the specified task. where Forkjointask represents a task that can be parallel and merged.
|
Client Non-Fork/join call |
Internal Call Fork/join |
Asynchronous execution |
Execute (forkjointask) |
Forkjointask.fork |
Waiting to get results |
Invoke (Forkjointask) |
Forkjointask.invoke |
Execute, get the future |
Submit (Forkjointask) |
Forkjointask.fork (Forkjointask is Futures) |
Forkjointask is the execution of a branch merge, and the business logic consumer of a branch merge can then inherit the first class of the extraction, implemented in the abstract method exec (). where EXEC () returns the result and forkjoinpool the execution of the caller (execute (...), invoke (...), submit (...) ) to determine whether a thread is blocked, see the test case below.
Forkjointask is an abstract class, and it has two abstract subclasses: Recurisivetask and Recurisiveaction.
Recurisivetask represents a task that has a return value. Recursivetask<t> is a generic class. T is the type of the return value.
Recurisiveaction represents a task that has no return value.
Exception handling
Forkjointask may throw an exception at execution time, but there is no way to catch the exception directly on the mainline thread, so Forkjointask provides the iscompletedabnormally () method to check if the task has been thrown or has been canceled. And the exception can be obtained by Forkjointask's GetException method. Use the following code:
if (task.iscompletedabnormally ()) { System.out.println (task.getexception ());}
The GetException method returns the Throwable object and returns cancellationexception if the task is canceled. Returns null if the task is not completed or if no exception is thrown.
Java Fork/join Framework