一,Fork-Join
1. Definition:
Fork-Join framework: arithmetic result is smaller tasks necessary in the case, a large task, split (the fork) into several small tasks (split removed when no longer), then one will be summarized join .
2,, Fork-Join reflects the divide and rule. What is divide and conquer?
The problem size N, when N <threshold value, directly address. When N> the threshold value, N is broken down into sub-problems k small-scale, independent of each other sub-problems, with the same form of the original problem. The de-merger of the sub-problems to get a big solution to the original problem.
3, taken adhesion work (workStealing)
4, Fork-Join combat
4.1, Fork / Join is a synchronous call while demonstrating the return value of the results: statistics integer array containing all elements and
/ * * * Integer array generating tools * / public class MakeArray { // array length public static Final int array_length = 4000 ; public static int [] makeArray () { // new new random number generator, the Random RD = new new the Random (); int [] = Result new new int [array_length]; for ( int I = 0 ; I <array_length; I ++ ) { // a random number to fill the array result[i] = rd.nextInt(ARRAY_LENGTH*3); } return result; } }
/ * * * Using the calculated frame Fork-Join * / public class SumArray { Private static class SumTask the extends RecursiveTask <Integer> { Private Final static int the THRESHOLD = MakeArray.ARRAY_LENGTH / 10 ; Private int [] the src; // to practical use array Private int fromIndex; // start statistics subscript Private int toIndex; // statistics to the end where the subscript public SumTask ( int [] src, int fromIndex, int toIndex){ this.src = src; this.fromIndex = fromIndex; this.toIndex = toIndex; } @Override protected Integer compute() { if(toIndex - fromIndex < THRESHOLD){ int count = 0; for(int i = fromIndex;i <= toIndex;i++){ try { Thread.sleep(1); } catch(InterruptedException E) { e.printStackTrace (); } COUNT = COUNT + the src [I]; } return COUNT; } the else { // fromIndex ..... ....... toIndex MID. An algorithm is here our own definition: greater than the threshold value is equally divided into two parts int MID = (fromIndex + toIndex) / 2 ; SumTask left = new new SumTask (the src, fromIndex, MID); SumTask right = new new SumTask (the src, MID, toIndex ); to invokeAll (left, right); return left.join() + right.join(); } } } public static void main(String[] args) { ForkJoinPool pool = new ForkJoinPool(); int[] src = MakeArray.makeArray(); SumTask innerFind = new SumTask(src,0,src.length-1); long start = System.currentTimeMillis(); pool.invoke(innerFind);//同步调用 System.out.println("Task is Running......."); . The System OUT .println ( " The IS COUNT " + innerFind.join () + " spend Time: " + (System.currentTimeMillis () - Start) + " MS " ); } / * * * Note: * For this simple add operation, in fact, single-threaded processing speed faster. * After use forkjoin, using multi-threaded processing. Because of the need to switch between threads (context switching), resulting in time spent handling forkjoin more. * Use forkjoin so must pay attention to the occasion. * This is why redis Although the use of single-process single-threaded mode, but the processing ability is very strong, because redis data processing is relatively simple (String). * Use a single-threaded process and avoid switching between processes. * / }
4.2, Fork / Join asynchronous call while the demo is not required to return value: traverse the specified directory (including subdirectories), looking for specific types of files
/ * * * Traverse the specified directory (including subdirectories), to find specific types of files * does not need to return the value of the Fork / the Join * / public class FindDirsFiles the extends RecursiveAction { // current tasks need to search the catalog Private File path; public FindDirsFiles ( path file) { the this .path = path; } @Override protected void Compute () { List <FindDirsFiles> = subtasks new new the ArrayList <> (); file [] files = path.listFiles (); // get the file directory IF (Files! = null ) { for(File File: Files) { if (file.isDirectory ()) { // for each subdirectory will create a sub-task subTasks.add ( new new FindDirsFiles (File)); } the else { // file is encountered, check if (. file.getAbsolutePath () endsWith ( " TXT " )) { . the System OUT .println ( " file: " + file.getAbsolutePath ()); } } } IF (! {subTasks.isEmpty ()) for(FindDirsFiles SubTask: to invokeAll (subtasks)) { // The above invlkeAll (): used to submit subtask subTask.join (); // wait for the subtask } } } } public static void main (String [] args) { the try { // with a total task scheduler instance ForkJoinPool ForkJoinPool the pool = new new ForkJoinPool (); FindDirsFiles task = new new FindDirsFiles ( new new File ( " D: \\ yishang " )); pool.execute (task); . The System OUT .println ( " Task running ........ IS " ); // main thread doing their own thing the try { the Thread.sleep ( . 1 ); } the catch (InterruptedException E) { e.printStackTrace ( ); } int otherWork = 0 ; for ( int I = 0 ; I < 100 ; I ++ ) { otherWork = otherWork + I; } the System. OUT.println("main Thread done sth ....., otherWork = "+otherWork); task.join();//阻塞方法, System.out.println("task end"); }catch (Exception e){ e.printStackTrace(); } } }