A series of Java Concurrency Programming: Executor framework

Source: Internet
Author: User

It is common for Java to use threads to complete asynchronous tasks, and the creation and destruction of threads requires a certain amount of overhead, and if each task requires creating a thread that consumes a lot of computing resources, then JDK 5 separates the unit of work from the execution mechanism, including runnable and callable, The implementation mechanism is provided by the executor framework. The executor framework facilitates thread initiation, execution, and shutdown, using thread pooling implementations at the bottom. The advantage of using the executor framework to manage threads is to simplify management, improve efficiency, and avoid this escaping problem--that is, incomplete objects are called by threads.

The executor framework uses a two-level scheduling model for thread scheduling. On the upper level, Java multithreaded applications typically decompose the application into multiple tasks, and then use the user scheduling framework executor to map these tasks to a fixed number of threads, and at the bottom, the operating system kernel maps these threads to the hardware processor.

Executor framework includes thread pool, executor,executors,executorservice,completionservice,future,c
Allable and so on.

The main thread first creates the task object through the runnable or callable interface. Tool class executors can encapsulate a Runnable object as a callable object (implemented by invoking Executors.callable (Runnable Task). The Runnable object can then be delivered directly to Executorservice execution, executorservice by calling Executorservice.execute (Runnable command) to complete the execution of the task Or give the Runnable object or callable object to Executorservice execution, executorservice by calling Executorservice.submit (Runnable Task) or Executorservice.submit (callable Task) to complete the submission of the task. When you use the Submit method of Executorservice, you return an object that implements the future interface (the Futuretask object is currently returned). Because Futuretask implements the runnable, you can also create the futuretask directly and then hand it over to executorservice execution.

The Executorservice interface inherits from the Executor interface, which provides a richer way to implement multithreading. For example, you can call Executorservice's shutdown () method to close executorservice smoothly, and after calling the method, it will cause Executorservice to stop accepting any new tasks and wait for the committed task to complete ( The tasks that have been submitted are divided into two categories: one that is already in place and one that has not yet started, and Executorservice will be closed when all the submitted tasks have been executed.

The Executors tool class allows you to create different thread pools Threadpoolexecutor:singlethreadexecutor, Fixedthreadpool, and Cachedthreadpool.

Fixedthreadpool

publicstaticnewFixedThreadPool(int nThreads)publicstaticnewFixedThreadPool(int nThreads,ThreadFactory factory)

The fixedthreadpool is suitable for applications that need to limit the current number of threads in order to meet the requirements of managing resources, and it is suitable for servers with heavier loads.

Singlethreadexecutor

publicstaticnewSingleThreadExecutor()publicstaticnewSingleThreadExecutor(ThreadFactory factory)

Singlethreadexecutor is suitable for scenarios where it is necessary to ensure that each task is executed sequentially, and that there will not be multiple threads in the active scene at any point in time.

Cachedthreadpool

publicstaticnewCachedThreadPool()publicstaticnewCachedThreadPool(ThreadFactory factory)

Cachedthreadpool is an unbounded thread pool that is suitable for small programs that perform many short-term asynchronous tasks, or servers that have a lighter load.

Scheduledthreadpoolexecutor

publicstaticnewScheduledThreadPool(int corePoolSize)publicstaticnewScheduledThreadPool(int corePoolSize,ThreadFactory factory)

Create a thread pool that supports timed and recurring task executions, which in most cases can be used to replace the timer class. The scheduledthreadpoolexecutor is intended for scenarios where multiple background threads are required to perform cycle tasks while limiting the number of background threads in order to meet resource management needs.

The core class of the executor framework is Threadpoolexecutor, which is the implementation class of the thread pool, consisting mainly of four components.

    1. Corepool: Size of the core thread pool
    2. Maximumpool: Size of the maximum thread pool
    3. Blockingqueue: Work queue to temporarily save a task
    4. Rejectedexecutionhandler: Saturation strategy. When the threadpoolexecutor is closed or the threadpoolexecutor is already saturated (meaning that the maximum thread pool size is reached and the work queue is full), the Execute method will call the handler


Perform runnable tasks using the executor framework

 Packagecom.rhwayfun.concurrency;ImportJava.util.concurrent.ExecutorService;ImportJava.util.concurrent.Executors;/** * Created by Rhwayfun on 16-4-4. * * Public  class executorrunnabletest {    StaticClass Runner implements runnable{ Public void Run() {System.out.println (Thread.CurrentThread (). GetName () +"is called"); }    } Public Static void Main(string[] args) {Executorservice Cachedthreadpool = Executors.newcachedthreadpool (); for(inti =0; I <5; i++) {Cachedthreadpool.execute (NewRunner ());    } cachedthreadpool.shutdown (); }}

The results are as follows:

By following the analysis of the Cachedthreadpool, you can know that the task is performed by selecting an idle thread from the thread pool to perform the task, and if there is no idle thread, a new thread is created to perform the task. The reason that the same thread is executed two times here is that the idle thread that performs the task does not terminate immediately after the task is executed, and the recognition waits 60 seconds before terminating.

Perform callable tasks using the executor framework

The Runnable task does not return a value and the callable task has a return value. and callable's call () method can only be executed through the Executorservice's submit (callable Task) method, and returns a future (currently Futuretask), which represents the future of the task waiting to be completed. If you need to get the result returned by callable execution, you can get it through the get method of the bucket futuretask.

The following code demonstrates the use of the executor framework to perform the callable task:

 Packagecom.rhwayfun.concurrency;ImportJava.util.ArrayList;ImportJava.util.List;Importjava.util.concurrent.*;/** * Created by Rhwayfun on 16-4-4. * * Public  class executorcallabletest {    /** * Callable Quest * *    StaticClass Runner implements Callable<string> {PrivateString runId; Public Runner(String runId) { This. runId = RunId; } PublicStringPager()throwsException {System.out.println (Thread.CurrentThread (). GetName () +"Call method is invoked!");returnThread.CurrentThread (). GetName () +"Call method and ID is"+ runId; }    } Public Static void Main(string[] args) {//thread poolExecutorservice Cachedthreadpool = Executors.newcachedthreadpool ();//Receive the return result of callable taskList<future<string>> futuretasklist =NewArraylist<future<string>> (); for(inti =0; I <5; i++) {future<string> future = Cachedthreadpool.submit (NewRunner (string.valueof (i)));        Futuretasklist.add (future); }//Traverse the returned results of thread execution         for(Future F:futuretasklist) {Try{//Busy waiting if the task is not completed                 while(!f.isdone ())            {} System.out.println (F.get ()); }Catch(Interruptedexception e)            {E.printstacktrace (); }Catch(Executionexception e)            {E.printstacktrace (); }finally{//Close the thread pool and no longer receive new tasksCachedthreadpool.shutdown (); }        }    }}

The running results of the program are as follows:

The Submit method also selects the idle thread to perform the task first, and if not, creates a new thread to perform the task. If the return of the future is not completed then the Get () method blocks the wait until the future completes the return.

Fixedthreadpool detailed

The source code for creating Fixedthreadpool is as follows:

publicstaticnewFixedThreadPool(int nThreads) {        returnnew ThreadPoolExecutor(nThreads, nThreads,                                      0L, TimeUnit.MILLISECONDS,                                      new LinkedBlockingQueue<Runnable>());    }

Its corepoolsize and maximumpoolsize are set to the value of nthreads. When the number of threads in the thread pool is greater than corepoolsize, KeepAliveTime is the maximum amount of time that an extra idle thread waits for a new task, and the extra thread will be terminated after that time. The implementation process for Fixedthreadpool is as follows:

    1. Create a new thread to perform a task if the number of threads currently running is less than corepoolsize
    2. Thread pool If the number of threads currently running equals corepoolsize, add the task to Linkedblockingqueue to wait for execution
    3. After the thread finishes performing the tasks in 1, it gets the task repeatedly from the Linkedblockingqueue in the loop to execute

Because of the unbounded queue used by Linkedblockingqueue, the threads in the thread pool do not exceed corepoolsize, so the tasks that continue to join the thread pool are executed, Because tasks that are not immediately executed are added to the linkedblockingqueue wait.

Cachedthreadpool detailed

Cachedthreadpool is a thread pool that creates threads as needed. Create a cachedthreadpool with the following source code:

publicstaticnewCachedThreadPool() {        returnnew ThreadPoolExecutor(0, Integer.MAX_VALUE,                                      60L, TimeUnit.SECONDS,                                      new SynchronousQueue<Runnable>());    }

From the source can be seen, Cachedthreadpool corepoolsize for 0,maximumpoolsize for Integer.max_value,keepalivetime for 60L, means that the extra idle thread waits 60 seconds for the new task to execute.

Cachedthreadpool uses synchronousqueue without capacity as the work queue for the thread pool (Synchronousqueue is a blocking queue with no capacity, and each insert must wait for the corresponding removal of another thread). But the maximumpool of Cachedthreadpool is unbounded. This means that if the thread is committed faster than the thread's processing speed, Cachedthreadpool will constantly create threads, in extreme cases because the creation thread runs out of CPU and memory resources too much.

The Cachedthreadpool is executed as follows:

    1. First, execute the Synchronousqueue offer method. If Maximumpool has an idle thread executing synchronousqueue.poll (keepalivetime,timeunit.nanoseconds), the primary thread performs an offer operation paired with the poll operation of the idle thread successfully , the main thread takes the task to the idle thread execution, otherwise executes 2
    2. If Maximumpool is empty or maximumpool does not have an idle thread, Cachedthreadpool will create a new thread to perform the task
    3. After the newly created thread finishes executing the task in step 2, it waits for 60 seconds in the Synchronousqueue queue, and if the main thread commits a new task within 60 seconds, the new task of the main thread submission will continue, or the idle thread will be terminated.
Scheduledthreadpoolexecutor detailed

Scheduledthreadpoolexecutor inherits from Threadpoolexecutor and is used primarily to perform tasks after a given delay, or to run tasks on a regular basis. The timer class also has a similar function, the timer corresponds to a single background thread, and scheduledthreadpoolexecutor can specify multiple corresponding background threads within the constructor.

Scheduledthreadpoolexecutor in order to support the execution of periodic tasks, Delayqueue is used as the task queue. The Scheduledthreadpoolexecutor will place the task to be dispatched (the task is scheduledfuturetask) in Delayqueue, and the thread in the thread pool gets the scheduled task to be performed from Delayqueue and executes.

The Scheduledfuturetask contains 3 variables:

    1. Long variable time, which is the task's specific execution times
    2. The long variable sequencenumber is the ordinal of the task that is added to the Scheduledthreadpoolexecutor
    3. Long member period, which indicates the interval between task execution

Here are scheduledthreadpoolexecutor specific steps to perform:

    1. The thread gets the scheduledfuturetask that has expired from Delayqueue. An expiration task is a task that has a time greater than or equal to the current
    2. Thread to perform this overdue task
    3. The time variable that the thread modifies for this task is the next execution (the current time plus the time interval)
    4. The thread puts the modified task back into the Delayqueue and is re-executed after it expires

A series of Java Concurrency Programming: Executor 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.