On the previous blog we introduced the thread synchronization through Cyclicbarrier, but there is a problem with the above method, that is, if a large task ran 2 threads to complete, if the thread 2 time consuming than thread 1 more than twice times, thread 1 completed must wait for thread 2 to complete, waiting for the process thread 1 can not be reused. Now that we're ready to solve this problem, we want thread 1 to be able to help thread 2 complete a portion of the task after it finishes its task. Java7 cited as the Fork/join framework can be a good solution to this problem.
Fork/join is a framework for executing tasks in parallel, a framework that divides large tasks into small tasks, and finally summarizes the results of a large task after each small task. Fork is fork, join is union. Here's a look at a picture to get a clear picture:
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 executing the Fork () and join () operations in a task, and typically we do not need to inherit the Forkjointask class directly, but only inherit its subclasses, the Fork/join framework provides the following two subclasses:
Recursiveaction: Used for tasks that do not return results.
Recursivetask: Used for tasks that have return results.
The forkjoinpool:forkjointask needs to be executed through Forkjoinpool, and the subtasks are added to the double-ended queue maintained by the current worker thread, to the head of the queue. When there is no task in the queue for a worker thread, it randomly fetches a task from the end of the queue of other worker threads.
Below, we also implement the test system to draw the example of the problem.
Getquestionstask.java
public class Getquestionstask extends recursivetask<list> {//parameter mapprivate Map map;//parameter list== only task questions private List Questiontypelist;public getquestionstask (List questiontypelist,map Map) {this.questiontypelist = questionTypeList; This.map=map;} @Overrideprotected List Compute () {System.out.println (Questiontypelist.size ()); List List = new ArrayList (), if (Questiontypelist.size () < 2) {//Draw list = Getquestions (Questiontypelist,map);} else {in T 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;} Merge drawing Results Private List groupresults (list list1, list list2) {System.out.println (Thread.CurrentThread (). GetName () + " Start merging results ... ");//merge return result LIST list = new ArrayList (); List.addall (List1); List.addall (LIST2); System.out.println (Thread.CurrentThread (). GetName () + "Merge results end ..."); return list; Draw the question private List getquestions (list questtypelist,map Map) {List List = new ArrayList (); for (int i=0;i<questtypelist.si Ze (); i++) {System.out.println (Thread.CurrentThread (). GetName () + "Start drawing questions ..." +questiontypelist.get (i). toString ()) ;//False data, put the question List.add ("0") to list, 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 will not exceed 0*7fff (32767)//The Forkjoinworkerthread object array is maintained in the pool, and 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);p Ool.execute (Task);//List of questions =task.get () try {List Finallist = Task.get (); System.out.println ("Number of final results:" + finallist.size ());} catch (Interruptedexception e) {e.printstacktrace ();} catch (Executionexception e) {e.printstacktrace ();}
Summarize:
Fork/join implements a "work-stealing algorithm" that randomly fetches a task from the end of another worker's queue when there is no task in the queue for 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 Best Not sleep ()
2. Threads must not perform I/O operations
3. Threads must not throw checked exception.
Java Concurrency Programming--fork/join framework uses