(iv) JUC thread advanced Features-thread pool/thread scheduling/Forkjoinpool

Source: Internet
Author: User

13. Thread Pool

The fourth way to get a thread: The thread pool, a executorservice, uses several possible pool threads to perform each submitted task, typically using the Executors factory method configuration.

The thread pool resolves two different issues: because of the reduced overhead of each task invocation, they typically provide enhanced performance when performing a large number of asynchronous tasks , and can also provide methods for binding and managing resources, including the threads used to execute the task set . Each threadpoolexecutor also maintains some basic statistical data, such as the number of completed tasks.

For ease of use across a wide range of contexts, this class provides a number of adjustable parameters and extension hooks (hooks). However, programmers are strongly advised to use the more convenient executors factory approach:

    • Executors.newcachedthreadpool () (No boundary pool, automatic thread recovery is possible)
    • Executors.newfixedthreadpool (int) (fixed size thread pool)
    • Executors.newsinglethreadexecutor () (single background thread)

They all pre-defined settings for most usage scenarios.

Create a thread pool with 5 threads to increase the operation of the variable

/** Thread pool: Provides a thread queue that holds all waiting states in the queue. Avoids the additional overhead of creating and destroying and increasing the speed of response.             * * Two, thread pool architecture: * Java.util.concurrent.Executor: Responsible for thread usage and scheduling root interface * |--**executorservice subinterface: main interface of thread pool * Implementation class for |--threadpoolexecutor thread pool * |--scheduledexecutorservice Sub-interface: Responsible for thread scheduling * |--scheduledt Hreadpoolexecutor: Inherit Threadpoolexecutor, implement Scheduledexecutorservice * Three, Tool class: Executors * Executorservice newFixedTh Readpool (): Create a fixed-size thread pool * executorservice Newcachedthreadpool (): Cache thread pool, the number of thread pools is not fixed, you can change the quantity automatically based on demand. * Executorservice Newsinglethreadexecutor (): Creates a single thread pool. There is only one thread in the thread pool * * Scheduledexecutorservice Newscheduledthreadpool (): Creates a fixed-size thread that can be deferred or timed to perform tasks. */ Public classTestthreadpool { Public Static voidMain (string[] args)throwsException {//1. Create a thread poolExecutorservice pool = Executors.newfixedthreadpool (5);ThreadPoolDemo TPD=NewThreadPoolDemo (); //2. Assigning a task to threads in a thread pool, >5, can call five threads of a line constructor         for(inti = 0; I < 10; i++) {pool.submit (TPD); }                //3. Close the thread poolPool.shutdown (); }    //new Thread (TPD). Start ();//new Thread (TPD). Start ();}classThreadPoolDemoImplementsrunnable{Private inti = 0; @Override Public voidrun () { while(I <= 100) {System.out.println (Thread.CurrentThread (). GetName ()+ ":" + i++); }    }   }

Thread pool creates threads with callable and future

 Public Static voidMain (string[] args)throwsException {//1. Create a thread poolExecutorservice pool = Executors.newfixedthreadpool (5); List<Future<Integer>> list =NewArraylist<>();  for(inti = 0; I < 10; i++) {        //the Future object is used to receive the return value of the callable threadfuture<integer> future = Pool.submit (NewCallable<integer>(){            //thread call method, query 1-100 and@Override PublicInteger Call ()throwsException {intsum = 0;  for(inti = 0; I <= 100; i++) {sum+=i; }                returnsum;        }                  });    List.add (future); }    //Close the thread poolPool.shutdown (); //Traverse result set, output 10 times 5050     for(future<integer>future:list)    {System.out.println (Future.get ()); }        }  
14. Thread Scheduling

The interface Scheduledexecutorservice inherits from the Executorservice interface, which is implemented by the Scheduledthreadpoolexecutor class (the subclass of the Threadpoolexecutor Class). You can schedule commands that run after a given delay or are executed on a regular basis.

Scheduledexecutorservice Newscheduledthreadpool (): Creates a fixed-size thread that can be deferred or timed to perform tasks.

Reference Java.util.concurrent.ScheduledThreadPoolExecutor.class in Schedule method source code

 Public<V> scheduledfuture<v> Schedule (callable<v>Callable,Longdelay, Timeunit unit) {        if(Callable = =NULL|| Unit = =NULL)            Throw NewNullPointerException (); Runnablescheduledfuture<V> T =Decoratetask (callable,NewScheduledfuturetask<v>(callable, Triggertime (delay, unit)));        Delayedexecute (t); returnT; }

Example:

 Public classTestscheduledthreadpool { Public Static voidMain (string[] args)throwsException {//to create a thread pool object of type ScheduledexecutorserviceScheduledexecutorservice pool = Executors.newscheduledthreadpool (5);
for(inti = 0; I < 5; i++) { future<Integer> result = Pool.schedule (NewCallable<integer>() {@Override PublicInteger Call ()throwsException {intnum =NewRandom (). Nextint (100);//Generate random numbersSystem.out.println (Thread.CurrentThread (). GetName () + ":" +num); returnnum; } }, 1, timeunit.seconds);
System.out.println (Result.get ()); } //thread pool shutdownPool.shutdown (); } }
Forkjoinpool Branch Merge framework-work stealing

Fork/join framework: is to be a large task, when necessary, to split (fork) into a number of small tasks (split to No re-disassembly), and then the results of a small task operations to Join summary.

  

/* @since 1.7 *   */  Public Abstract class Implements Future<v>, Serializable {...}
    • use "work-stealing" mode (work-stealing): when you perform a new task, it splits it into smaller tasks, adds small tasks to the thread queue, and then steals one from the queue of a random thread and puts it in its own queue.

    • The advantages of the Fork/join framework in relation to the general thread pool implementations are in the way that the tasks contained therein are handled. In a generic thread pool, a thread is waiting if a task that is being performed by a thread cannot continue to run for some reason. In the Fork/join framework implementation, a sub-problem cannot continue to run because it waits for the completion of another sub-problem. The thread that handles the sub-problem is actively looking for other sub-problems that are not yet running. This approach reduces thread latency and improves performance.

After jdk1.7, two fork/join frames are provided, and the maximum difference between two frames is whether there is a return value

// has a return value  Public Abstract class extends Forkjointask<v> {}// no return value publicabstractclass extends forkjointask<void> {}

The following is an example of an implementation (for the sum of all the numbers between two numbers, such as 1-100-->5050):

classForkjoinsumcalculateextendsRecursivetask<long>{    Private Static Final LongSerialversionuid = -1812835340478767238l; Private Longstart; Private Longend; Private Static Final LongThurshold = 10000L;//Critical Value         PublicForkjoinsumcalculate (LongStartLongend) {         This. Start =start;  This. end =end; } @OverrideprotectedLong Compute () {LongLength = end-start; //is less than the critical value, the sum of all the numbers between the initial value and the ending value is calculated directly without splitting        if(Length <=thurshold) {            Longsum = 0L;  for(Longi = start; I <= end; i++) {sum+=i; }                        returnsum; }Else{//greater than the critical value, take the middle value to split, recursive call            LongMiddle = (start + end)/2; Forkjoinsumcalculate Left=Newforkjoinsumcalculate (start, middle); Left.fork (); //to split and press into the thread queueForkjoinsumcalculate Right=NewForkjoinsumcalculate (middle+1, end); Right.fork (); //                        returnLeft.join () +Right.join (); }    }    }

Test 1-50000000000 's and:

 Public Static void Main (string[] args) {     = instant.now ();              New Forkjoinpool ();             ForkjointaskNew forkjoinsumcalculate (0L, 50000000000L);              = Pool.invoke (Task);             SYSTEM.OUT.PRINTLN (sum);              = Instant.now ();             System.out.println ("time-consuming:" + Duration.between (start, end). Tomillis ()); }

Result: CPU utilization reaches 100%, time consuming 19.361s

And for the For loop add a comparison:

 Public void test1 () {     = instant.now ();              long sum = 0L;               for (long i = 0L; I <= 50000000000L; i++) {         + = i;     }             SYSTEM.OUT.PRINTLN (sum);              = Instant.now ();             System.out.println ("time-consuming:" + duration.between (start, end). Tomillis ()); // 35-3142-15704 }

The results are as follows: Time consuming 18.699s

Since the Fork/join framework is not easy to split in complex logic, JAVA8 has been improved for fork/join, as shown in the following code:

// java8 new Features  publicvoid  test2 () {     = instant.now ();              = longstream.rangeclosed (0L, 50000000000L)                          . Parallel ()                          . Reduce (0L, long::sum);             SYSTEM.OUT.PRINTLN (sum);              = Instant.now ();            System.out.println ("time-consuming:" + duration.between (start, end). Tomillis ()); // 1536-8118 }

Result: Time consuming 15.428s

Tested several values and found efficiency aspects: Java8 > For loop > Fork/join

10000000000L
50000000000L
100000000000L
Java8 3320ms 15428ms 34770ms
For 3902ms 18699ms 37858ms
Fork/join 4236ms 19361ms 40977ms

Logically, as the computational volume increases, the efficiency of the fork/join will exceed the for loop, but the result of the native test is that the Fork/join framework is always less efficient than the for loop at the bottom. This aspect may lie in the compute method design in the long type of packing and unpacking has a certain time cost, on the other hand may because the critical value selection is unreasonable, the test is selected 10000, in the test 10000000000L accumulation, the use of four critical values: 5000, 10000, 20000, 100000, the result is the most efficient when the critical value is 10000. Still believe that seeing is the truth.

(iv) JUC thread advanced Features-thread pool/thread scheduling/Forkjoinpool

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.