"Java.util.concurrent package source reading" The first experience of the Fork/join framework

Source: Internet
Author: User

JDK7 introduced the Fork/join framework, the so-called Fork/join framework, a personal explanation: fork decomposition tasks into separate sub-tasks, with multithreading to perform these subtasks, join merge subtasks results. This enables you to perform a task in a multi-threaded manner.

The fork/join introduced by JDK7 has three core classes:

Forkjoinpool, the thread pool that executes the task

Forkjoinworkerthread, the worker thread that performs the task

Forkjointask, a task abstract class for Forkjoinpool.

Because Forkjointask is more complex, abstract methods are more, daily use generally do not inherit forkjointask to achieve the custom task, but inherit the forkjointask of the two sub-classes:

Recursivetask: Child task with return result when used

Recursiveaction: Child tasks are used without returning results

For the principles of the Fork/join framework, Doug Lea's article:A Java fork/join Framework

After looking at many examples on the web, it is common to find the logic of implementing the Compute method in a custom task class:

if The task is small enough to    directly return the result or else     to split into N subtasks    , calling each child task in turn, and then executing the child task by    calling the join method of each child task to merge the execution results 

The call to execute the custom task is Forkjoinpool's Execute method, so the first thing to look at is the Forkjoinpool execute method, to see how the task is different from the normal thread pool:

     Public void Execute (forkjointask<?> Task) {        ifnull)             thrownew  nullpointerexception ();        Forkorsubmit (Task);    }

So forkorsubmit is the real way to execute Forkjointask:

    Private<T>voidForkorsubmit (forkjointask<t>Task)        {Forkjoinworkerthread W; Thread T=Thread.CurrentThread (); if(Shutdown)Throw Newrejectedexecutionexception (); if((tinstanceofForkjoinworkerthread) &&(W= (forkjoinworkerthread) t). Pool = = This) W.pushtask (Task); Else            //normal execution is called by the main thread, so focus on addsubmissionaddsubmission (Task); }

So the first thing we should focus on is the Addsubmission method, and find that what we do is similar to the normal thread pool, which is to add the task to the queue, and the other is to use unsafe to manipulate the memory for adding the Task object.

    Private voidAddsubmission (forkjointask<?>t) {FinalReentrantlock lock = This. Submissionlock;        Lock.lock (); Try {            //The queue is just an ordinary array instead of the blockingqueue of the normal thread pool,//The work of waking up the worker thread is done by the following signalwork//using unsafe for memory operations, placing tasks in arraysForkjointask<?>[] Q;intS, m; if((q = submissionqueue)! =NULL) {                LongU = (((s = queuetop) & (M = q.length-1)) << Ashift) +Abase;                Unsafe.putorderedobject (q, U, t); Queuetop= s + 1; if(S-queuebase = =m)//array is full, scaling is expanded for arraysGrowsubmissionqueue (); }        } finally{lock.unlock (); }        //notifies you that a new task has been made: two operations, with idle threads waking the thread//Otherwise, if you can create a new worker thread, create a new worker thread for this task//if it is not possible to return, wait until there are idle threads to perform this tasksignalwork (); }

The next thing to figure out is that when you fork in the compute, the action is executed in the same thread as the main task, and Fork is executed if the task becomes multithreaded:

     Public Final forkjointask<v> Fork () {(        (forkjoinworkerthread) Thread.CurrentThread ())            . Pushtask (  this);         return  This ;    }

In the above analysis Forkorsubmit also saw the forkjoinworkerthread pushtask method call, then see this method:

    Final voidPushtask (forkjointask<?>t) {//The basic logic of code and the Addsubmission method of Forkjoinpool are basically consistent//is to add the task to the task queue, which is added to the Forkjoinworkerthread//built-in task queueForkjointask<?>[] Q;intS, m; if((q = queue)! =NULL) {//Ignore if queue removed            LongU = (((s = queuetop) & (M = q.length-1)) << Ashift) +Abase;            Unsafe.putorderedobject (q, U, t); Queuetop= s + 1;//or use Putorderedint//It's not quite clear .            if((S-= queuebase) <= 2) pool.signalwork (); Else if(s = =m) growqueue (); }    }

See here all of a sudden into the deadlock, why Forkjoinworkerthread to build a queue, and if the sub-task is still in the same line range, how to implement concurrent sub-task? The next article continues.

Java.util.concurrent package Source Reading Fork/join The first experience of the framework

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.