Last blog we introduced the thread synchronization through Cyclicbarrier, but the problem with this approach is that if a large task runs 2 threads to complete, if the thread 2 takes more than 1 twice times the thread, the thread 1 completes and waits for the thread 2 to complete, and the waiting process thread 1 cannot be reused. Now that we're ready to solve this problem, we want thread 1 to help thread 2 complete a portion of the task after completing its own task. Java7 as a fork/join framework can be a good solution to this problem.
Fork/join is a framework for parallel execution of tasks, a framework that divides large tasks into small tasks, and finally summarizes the results of each small task. Fork is a fork, join is a union. Look at the picture below to get a clear understanding of:
In fact, Fork/join is essentially an implementation of the divide-and-conquer algorithm. Let's look at how to use it specifically:
Forkjointask: To use the Fork/join framework, you must first create a fork/join task. It provides a mechanism for performing Fork () and join () operations in a task, usually without inheriting the Forkjointask class directly, but only inheriting its subclasses, and the Fork/join framework provides the following two subclasses:
Recursiveaction: For tasks that do not return results.
Recursivetask: For tasks that have return results.
Forkjoinpool:forkjointask needs to be performed through Forkjoinpool, and subtasks are added to the two-terminal queues maintained by the current worker thread to the head of the queue. When a worker thread does not have a task in its queue, it randomly obtains a task from the tail end of the queue of other worker threads.
Below, we also achieve the test system to draw examples of problems. Getquestionstask.java
public class Getquestionstask extends recursivetask<list> {//parameter map private map map;
Parameter list== only type private List questiontypelist;
Public Getquestionstask (List questiontypelist,map Map) {this.questiontypelist = questiontypelist;
This.map=map;
} @Override protected List Compute () {System.out.println (Questiontypelist.size ());
List List = new ArrayList ();
if (Questiontypelist.size () < 2) {//Draw title List = Getquestions (Questiontypelist,map);
else {int size = Questiontypelist.size ();
int mid = SIZE/2;
Getquestionstask Task1 = new Getquestionstask (questiontypelist.sublist (0, mid), map);
Getquestionstask task2 = new Getquestionstask (Questiontypelist.sublist (Mid, size), map);
InvokeAll (Task1, Task2);
try {list = Groupresults (Task1.get (), Task2.get ());
catch (Interruptedexception e) {e.printstacktrace ();
catch (Executionexception e) {e.printstacktrace ();
} return list; }//Combined with the results of the problem PrivaTe list groupresults (list list1, list list2) {System.out.println (Thread.CurrentThread (). GetName () + "Start merging results ...");
Merge return result list = new ArrayList ();
List.addall (List1);
List.addall (LIST2);
System.out.println (Thread.CurrentThread (). GetName () + "Merge results end ...");
return list;
//Extract Private list getquestions (list Questtypelist,map Map) {List List = new ArrayList (); for (int i=0;i<questtypelist.size (); i++) {System.out.println (Thread.CurrentThread (). GetName () + "Start drawing questions ..." +
Questiontypelist.get (i). toString ());
False data, to the list of questions List.add ("0");
List.add ("1");
List.add ("2");
List.add ("3");
List.add ("4");
try {thread.sleep (1000);
catch (Interruptedexception e) {e.printstacktrace ();
} System.out.println (Thread.CurrentThread (). GetName () + "Draw end ..." +questiontypelist.get (i). toString ());
} return list; }
}
Client:
The number of threads in the pool is not more than 0*7FFF (32767)
//pool-maintained Forkjoinworkerthread object array, the array size is determined by the Parallelism property, parallelism defaults to the number
of processors Forkjoinpool pool = new Forkjoinpool ();
Getquestionstask task = new Getquestionstask (questiontypelist, map);
Pool.execute (Task);
Question List =task.get ()
try {
list finallist = Task.get ();
SYSTEM.OUT.PRINTLN ("End result number:" + finallist.size ());
} catch (Interruptedexception e) {
e.printstacktrace ();
} catch (Executionexception e) {
E.printstacktrace ();
}
Summarize:
Fork/join implements the "work-stealing algorithm", which randomly retrieves a task from the end of the queue of other worker threads when there is no task in the queue of a worker thread. Of course, the use of the FORK/JOIN framework has certain constraints:
1. In addition to the fork () and join () methods, threads must not use other synchronization tools. Thread is best not to sleep ()
2. Threads must not do I/O operations
3. Threads must not throw checked exception.