Java Concurrent Programming: Completionservice__java

Source: Internet
Author: User
Tags dateformat throwable time limit

Completionservice Introduction

Completionservice and Executorservice can be used to perform the tasks of the thread pool, Executorservice inherits the executor interface, and Completionservice is an interface, So why Completionservice not directly inherit the executor interface. Primarily executor, the executor framework does not fully guarantee the asynchronous nature of task execution, that is, if you need to implement the asynchronous nature of tasks (Task), the asynchronous nature of the task is achieved by creating a thread for each task. Code often contains the new Thread (Task). Start (). The problem with this approach is that it does not limit the number of threads that can be created (Executorservice can be limited), but the biggest problem is that in high concurrency, creating threads to perform tasks asynchronously will greatly increase the overhead of thread creation , It causes great resource consumption and affects the stability of the system . In addition, the executor framework also supports the execution of synchronization tasks, in which the run () method that invokes the submit task in the Execute method belongs to a synchronous call.

In general, if you need to determine whether a task is completed, the idea is to get each future of the future list, and then call its getting method repeatedly, and set the timeout parameter to 0 to determine whether the task is completed by polling. Completionservice can be used to achieve more precise asynchronous execution of tasks and to perform asynchronous execution of tasks more easily.

Completionservice Realization Principle

Completionservice can actually be seen as a combination of executor and blockingqueue. Completionservice gets the results of a task execution through a similar blockingqueue put and take when it receives a task to perform. A realization of completionservice is to executorcompletionservice,executorcompletionservice the specific task of computing to executor completion.

On implementation, Executorcompletionservice creates a blockingqueue in the constructor (the unbounded queue Linkedblockingqueue used based on the linked list), The role of the blockingqueue is to save the results of executor execution. When the calculation is complete, the done method of the Futuretask is invoked. When submitting a task to Executorcompletionservice, first wrap the task into queueingfuture, it is a subclass of Futuretask, and then rewrite the Futuretask done method, The results of the executor execution are then put into the blockingqueue. Queueingfuture source code is as follows:

   Private class Queueingfuture extends Futuretask<void> {
       queueingfuture (runnablefuture<v> Task) {
           Super (task, NULL);
           This.task = task;
       }
       protected void Done () {Completionqueue.add (Task);}
       Private final future<v> task;
   }
   
   

As you can see from the code, Completionservice translates the submitted task into queueingfuture and overwrites the Done method, in which the task is added to the task queue. This is consistent with the previous analysis of the executor framework.

using Executorservice to implement tasks

The code simulates the operation of loading the product details in the electrical quotient, because of the variety of commodity attributes, so you can display the picture of the product and the display of the product profile as two independently performed tasks. In addition, because the picture of the product may have many sheets, the display of the picture tends to be slower than the profile display. Asynchronous execution at this time can speed up execution to a certain extent and improve the performance of the system. The following code demonstrates this:

Package com.rhwayfun.patchwork.concurrency.r0410;
Import Java.text.DateFormat;
Import Java.text.SimpleDateFormat;
Import java.util.ArrayList;
Import Java.util.Date;
Import java.util.List;

Import java.util.concurrent.*;
 /** * Created by Rhwayfun on 16-4-10. * * public class Displayproductinfowithexecutorservice {//thread pool private final executorservice Executorservice = Exe
    Cutors.newfixedthreadpool (2);

    Date Formatter private final DateFormat format = new SimpleDateFormat ("HH:mm:ss"); Simulate the Electronic Business website Product details information display//As a possible product picture may have a lot of Zhang, so display the picture of the product will often have a certain delay//In addition to the details of the goods also include merchandise information such as the display, because the information here is the main text//master, so can be more than the picture Show it quickly. The following code takes the execution of these two tasks as the main thread and ends//into the execution of these two tasks. Because of the large gaps in the implementation of these two tasks, so the thought of the first//idea is asynchronous execution, the first execution of the image download task, after (not very long) start the implementation of the product//profile information display, if the network is good enough, the picture is not very large case, may be at the beginning of the show//product

    When the image is downloaded, it is natural to think of using executor and callable to complete the implementation of the XOR/step task.

        public void Renderproductdetail () {final list<productinfo> Productinfos = Loadproductimages (); Tasks for downloading images asynchronously callable< list<productimage>> task = new callable<list<productimage>> () {@Override PU Blic list<productimage> Call () throws Exception {list<productimage> imageList = new ArrayList
                <> ();
                for (ProductInfo Info:productinfos) {Imagelist.add (Info.getimage ());
            return imageList;

        }
        };
        Commit to thread pool execution future<list<productimage>> listfuture = executorservice.submit (Task);

        Information Renderproducttext (PRODUCTINFOS) showing the product profile;
            try {//display the picture of the product list<productimage> imageList = Listfuture.get ();
        Renderproductimage (imageList); catch (Interruptedexception e) {//If the display of a picture breaks an exception reset the interrupt state of the thread//This allows the thread in wait to wake up THR
            Ead.currentthread (). interrupt (); Cancels the execution of the task at the same time, and the parameter false indicates that the thread is executing without interrupting listfuture.cancel (true);
            catch (Executionexception e) {try {throw new Throwable (E.getcause ());
            catch (Throwable throwable) {throwable.printstacktrace (); }} private void Renderproductimage (List<productimage> imageList) {for (Productimage I
            Mage:imagelist) {try {TimeUnit.SECONDS.sleep (1);
            catch (Interruptedexception e) {e.printstacktrace ();
            } System.out.println (Thread.CurrentThread (). GetName () + "Display Products images!"
    + Format.format (new Date ()); } private void Renderproducttext (List<productinfo> Productinfos) {for (ProductInfo Info:productinfos
            {try {thread.sleep (50);
            catch (Interruptedexception e) {e.printstacktrace (); } System.out.println (Thread.CurrentThread (). GetnAme () + "Display Products description!"
    + Format.format (new Date ()); Private List<productinfo> Loadproductimages () {list<productinfo> List = new Arraylist<> (
        );
        try {TimeUnit.SECONDS.sleep (5);
        catch (Interruptedexception e) {e.printstacktrace ();
        } productinfo info = new ProductInfo ();
        Info.setimage (New Productimage ());
        List.add (info);
                System.out.println (Thread.CurrentThread () getName () + "Load Products info!"
        + Format.format (new Date ());
    return list;

        /** * Commodity * * private static class productinfo{private productimage image;
        Public Productimage GetImage () {return image;
        public void SetImage (productimage image) {this.image = image; } private static Class productimage{} public static void Main (string[] args) {DisPlayproductinfowithexecutorservice cd = new Displayproductinfowithexecutorservice ();
        Cd.renderproductdetail ();
    System.exit (0);
 }
}

The code performs the following results:

In the above code, try to execute the task of downloading and briefing information in parallel, although this method can complete the task, but the parallel performance of heterogeneous tasks is limited. Consider an extreme case where the download speed of a product picture is far less than the loading of the introductory information, and this situation (usually the ratio of the load to the two will be a larger value) is actually more efficient than the serial execution of the task. and using more complex code, the improvement is so small. The improvement of system performance is significant only if the equivalent independent and homogeneous task can be processed concurrently (because the load picture and profile execution speed vary too much, so it is not an isomorphic task).

using Completionservice to implement tasks

A major improvement in using Completionservice is to distribute multiple picture loads to multiple units of work, thus narrowing the gap between the loading of a product picture and the speed at which it is loaded, so that these small tasks are executed in the thread pool, This greatly reduces the time to download all the pictures, so at this point the two tasks can be considered isomorphic. Using Completionservice is the perfect place to do it.

Package com.rhwayfun.patchwork.concurrency.r0410;
Import Java.text.DateFormat;
Import Java.text.SimpleDateFormat;
Import java.util.ArrayList;
Import Java.util.Date;
Import java.util.List;

Import java.util.concurrent.*;
 /** * Created by Rhwayfun on 16-4-10.
    * * public class Displayproductinfowithcompletionservice {//thread pool private final executorservice executorservice;

    Date Formatter private final DateFormat format = new SimpleDateFormat ("HH:mm:ss"); Public Displayproductinfowithcompletionservice (Executorservice executorservice) {this.executorservice = ExecutorS
    Ervice;

        public void Renderproductdetail () {final list<productinfo> Productinfos = Loadproductinfos (); completionservice<productimage> completionservice = new Executorcompletionservice<productimage> (

        Executorservice); Create a work task for each image download (final ProductInfo Info:productinfos) {Completionservice.submit (new callable <productimAge> () {@Override public productimage call () throws Exception {re
                Turn info.getimage ();
        }
            });

        (renderproducttext)//presentation of information on the product profile (Productinfos); try {//Show product picture for (int i = 0, n = productinfos.size (); i < n; i++) {future<
                productimage> imagefuture = Completionservice.take ();
                Productimage image = Imagefuture.get ();
            Renderproductimage (image);
            } catch (Interruptedexception e) {//If the display of a picture breaks an exception reset the interrupt state of the thread//This allows the thread in wait to wake up
        Thread.CurrentThread (). interrupt ();
            catch (Executionexception e) {try {throw new Throwable (E.getcause ());
            catch (Throwable throwable) {throwable.printstacktrace (); }} private void Renderproductimage (productimage image{try {thread.sleep (100);
        catch (Interruptedexception e) {e.printstacktrace ();
                } System.out.println (Thread.CurrentThread (). GetName () + "Display Products images!"
    + Format.format (new Date ()); } private void Renderproducttext (List<productinfo> Productinfos) {for (ProductInfo Info:productinfos
            {try {thread.sleep (50);
            catch (Interruptedexception e) {e.printstacktrace ();
                } System.out.println (Thread.CurrentThread (). GetName () + "Display Products description!"
    + Format.format (new Date ()); Private List<productinfo> Loadproductinfos () {list<productinfo> List = new Arraylist<> ()
        ;
        try {TimeUnit.SECONDS.sleep (3);
        catch (Interruptedexception e) {e.printstacktrace (); } productinfo info = NEW ProductInfo ();
        Info.setimage (New Productimage ());
        List.add (info);
                System.out.println (Thread.CurrentThread () getName () + "Load Products info!"
        + Format.format (new Date ());
    return list;

        /** * Commodity * * private static class ProductInfo {private productimage image;
        Public Productimage GetImage () {return image;
        public void SetImage (productimage image) {this.image = image; } private static class Productimage {} public static void Main (string[] args) {Displayproduc
        Tinfowithcompletionservice cd = new Displayproductinfowithcompletionservice (Executors.newcachedthreadpool ());
    Cd.renderproductdetail ();
 }
}

The execution results are the same as above. Because multiple Executorcompletionservice can share a executor, you can create a private one for a particular calculation and share a common executor executorcompletionservice.

The Completionservice Summary performs asynchronous tasks more accurately and easily than Executorservice,completionservice One of the implementations of Completionservice is Executorcompletionservice, which is a fusion of executor and Blockingqueue functions, executor completes the computing task, Blockingqueue is responsible for saving the execution results of an asynchronous task when performing a large number of mutually independent and homogeneous tasks, you can use Completionservice Completionservice to set a time limit for the execution of a task. It is mainly through the Blockingqueue poll (long time,timeunit unit) to limit the results of the task execution and cancel the task if it is not completed

In other posts to see the Completionservice and executor of the statement, feel very useful, as follows:

1.completionservice.take gets and clears the results of the task that has been completed, blocking if no task is currently completed. 2. "First create a collection of future types, add the return value of the task submitted by executor to the collection, and finally traverse the collection to fetch the data" – this method is usually in the order in which future is added. The biggest difference between the two methods is the sequence of traversal Future, which is relatively completionservice performance. Consider the following scenario: Multithreading download, the results are returned with future. The first file is very large and the following files are small. With Method 1, you can quickly know the results of a file that has been downloaded (not the first), and with Method 2, you must wait until the first file is downloaded before you get the download results for other files.

Reference Address: http://blog.csdn.net/ghsau/article/details/7451464


This article turns from:
http://blog.csdn.net/u011116672/article/details/51113769

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.