Java multithreaded development, executors, Futuretask, callable

Source: Internet
Author: User
Tags getmessage thread class keep alive

Java multithreading How to apply it, almost learn Java students know the thread class and Runable interface. To inherit the thread class or implement the Runable interface, invoke the thread's Start method to start the threads.

Then there is the thread pool, which is the start of a series of threads, and when a thread needs to be started, a thread is taken from the thread pools.

Recently used to require a thread to start a complex operation and get its return value.

You use the callable.

 Public Interface Callable<v> {    /**     * Computes a result, or throws an exception if unable to does so.     *     @return  computed result     @throws  Exception If unable to compute a Result     *   /throws Exception;}    

Callable interface is from the jdk1.5, which uses the call method instead of the run method, compared to runable: can have a return value, can also throw an exception, these two points is the main reason for the introduction of callable

Callable how to use it will have a return value: First an example in one by one to explain;

Executorservice executor =Executors.newsinglethreadexecutor (); Future<String> future = Executor.submit (NewMyTask ()); String result=NULL; Try {result= (String) future.get (3, timeunit.minutes);         } Catch(TimeoutException e) {log.error ("Timeoutexception!"); } Catch(interruptedexception e) {log.error ("Interruptedexception:" +e.getmessage ()); } Catch(executionexception e) {log.error ("Executionexception:" +e.getmessage ()); }

(i). The use of executors

The top interface of the thread pool in Java is executor, but strictly speaking, executor is not a thread pool, but a tool for executing threads. The real thread pool interface is executorservice.

To configure a thread pool is more complex, especially if the thread pool principle is not very clear, it is likely that the thread pool configured is not superior, so there are some static factories in the executors class that generate some common thread pools.

1. Newsinglethreadexecutor

Creates a single threaded pool of threads. This thread pool has only one thread at work, which is equivalent to single-threaded serial execution of all tasks. If this unique thread ends because of an exception, a new thread will replace it. This thread pool guarantees that the order in which all tasks are executed is performed in the order in which the tasks are submitted.

2.Newfixedthreadpool

Creates a fixed-size thread pool. Each time a task is committed, a thread is created until the thread reaches the maximum size of the threads pool. Once the maximum size of the thread pool is reached, the thread pool will be replenished with a new thread if it ends up executing an exception.

3. Newcachedthreadpool

Creates a cacheable pool of threads. If the size of the thread pool exceeds the thread that is required to process the task,

Then a partially idle (60 second non-performing) thread is reclaimed, and when the number of tasks increases, the thread pool can intelligently add new threads to handle the task. This thread pool does not limit the size of the thread pool, and the thread pool size is entirely dependent on the maximum thread size that the operating system (or JVM) can create.

4.Newscheduledthreadpool

Create a thread pool of unlimited size. This thread pool supports the need to schedule and periodically perform tasks.

We used the newsinglethreadexecutor to create a single thread pool, flipping through the source to see what's going on inside.

 Public Static Executorservice Newsinglethreadexecutor () {        returnnew  Finalizabledelegatedexecutorservice            (new threadpoolexecutor (1, 1,                                    0L, Timeunit.milliseconds,                                    new linkedblockingqueue<runnable>()));    }

OK, create a proxy thread pool to handle single-threaded problems, which are thrown into one thread with only one thread and a maximum value of 1.

The agent thread pool first needless to say, actually inside calls is also the complete Threadpoolexeutor method, first to parse the Threadpoolexeutor parameter:

The signature of Threadpoolexecutor's complete construction method is:threadpoolexecutor (int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) .

corepoolsize -The number of threads that are saved in the pool, including idle threads.

maximumpoolsize-The maximum number of threads allowed in the pool.

KeepAliveTime -When the number of threads is greater than the core, this is the maximum time to wait for a new task before terminating the extra idle thread.

Unit-the time units of the KeepAliveTime parameter.

WorkQueue -the queue used to hold the task before execution. This queue keeps only the runnable tasks that are submitted by the Execute method.

Threadfactory -The factory that the executor uses when it creates a new thread.

Handler -the handler that is used when execution is blocked because the thread range and queue capacity are exceeded.

Threadpoolexecutor is the underlying implementation of the Executors class.

(b). Executor.submit

Now that you've used the Submit method, take a look at what's going on in the submit:

 Public <T> future<t> Submit (callable<t> Task) {            return  e.submit (Task);        } // This is the Delegatedexecutorservice method, and this class is the parent class of Finalizabledelegatedexecutorservice,
See that he is actually calling Threadpoolexecutor's Submit method, whose arguments are of type callable. T is a return value type
   Public<T> future<t> Submit (callable<t>Task) {        if(Task = =NULL)Throw NewNullPointerException (); Runnablefuture<T> Ftask =newtaskfor (Task);        Execute (ftask); returnFtask; }   protected<T> runnablefuture<t> newtaskfor (callable<t>callable) {        return NewFuturetask<t>(callable); }//This is the method in the Abstractexecutorservice class, which is the parent class of the Threadpoolexecutor and implements the Executorservice interface

As a result, futuretask implementation of the Runable interface, so the implementation of callable process is actually started a runable to perform callable, to facilitate better control.

voidInnerrun () {if(!compareandsetstate (0, RUNNING)) return; Try{Runner=Thread.CurrentThread (); if(getState () = = RUNNING)//recheck after setting threadInnerset (Callable.call ()); Elsereleaseshared (0);//Cancel}Catch(Throwable ex) {innersetexception (ex); }        }
This is the implementation of the Run () in Futuretask, where it says that the return value of the call () method is assigned to result and eats the exception, as for why we say

Futuretask is the realization of the future interface, the future interface mainly has these methods to control its callable tasks:
A, Boolean Cancel (Boolean mayinterruptlfrunning): Attempted to cancel the callable task associated with the future
B, V get (): Returns the return value of the call method in the callable task, which causes the thread to block and must wait until the child thread ends to get the return value
C, V get (long timeout, timeunit unit): Returns the return value of the call method in the callable task, which allows the program to block timeout and the time specified by the unit.
If the callable task still has no return value after the specified time, TimeoutException will be thrown.
D, Boolean iscancelled: Returns True if the callable task is canceled before it is properly completed.
E, Boolean IsDone: Returns True if the callable task has completed

It is primarily the get () method, which is the method that gets the return value of the thread. This is blocking, that is, when a get is called, it waits for the thread to end before it returns, otherwise it waits or waits longer than the timeout.

Remember when run ate an exception, where the exception that was eaten would be thrown out here: So, if you do not call the Get () method, then the calling method executed does not throw an exception, and there is no return value, which is the same as the normal runable.

This is the main implementation of get
V Innerget (LongNanostimeout)throwsinterruptedexception, Executionexception, timeoutexception {if(!tryacquiresharednanos (0, Nanostimeout)) Throw Newtimeoutexception (); if(getState () = =CANCELLED)Throw Newcancellationexception (); if(Exception! =NULL) Throw Newexecutionexception (Exception); returnresult; }

(c): Executorservice also offers some other methods, such as breaking threads:

(iv): excerpt some

Here are a few classes of source code:

Executorservice newfixedthreadpool (int nthreads): fixed-size thread pool.

As you can see, the size of the corepoolsize and Maximumpoolsize is the same (in fact, the maximumpoolsize parameter is meaningless if you use the unbounded queue), What is the value table name for KeepAliveTime and unit? -That's the implementation don't want to keep alive! The last Blockingqueue chose Linkedblockingqueue, the queue has a characteristic that he is unbounded.

1. public static executorservice newfixedthreadpool (int nthreads) {

2. Return new Threadpoolexecutor (Nthreads, Nthreads,

3.0L, Timeunit.milliseconds,

4. New linkedblockingqueue<runnable> ());

5.}

Executorservice Newsinglethreadexecutor (): Single thread

1. public static Executorservice Newsinglethreadexecutor () {

2. Return new Finalizabledelegatedexecutorservice

3. (New Threadpoolexecutor (1, 1,

4.0L, Timeunit.milliseconds,

5. New linkedblockingqueue<runnable> ()));

6.}

Executorservice Newcachedthreadpool (): No boundary pool, automatic thread recovery

This implementation is interesting. The first is the unbounded thread pool, so we can find maximumpoolsize as big big. followed by the Blockingqueue selection on the use of Synchronousqueue. May be a little strange for the blockingqueue, simply said: In the queue, each insert operation must wait for the corresponding removal of another thread.

1. public static Executorservice Newcachedthreadpool () {

2. Return new Threadpoolexecutor (0, Integer.max_value,

3.60L, Timeunit.seconds,

4. New synchronousqueue<runnable> ());

    1. }

Start with the Blockingqueue<runnable> workqueue the first entry. In the JDK, it has been made clear that there are three types of queue.

All blockingqueue can be used to transfer and maintain submitted tasks. You can use this queue to interact with the pool size:

If you run fewer threads than corepoolsize, executor always prefers to add new threads without queuing. (if the currently running thread is less than corepoolsize, the task will not be stored at all, added to the queue, but directly to the guy (thread) to start running)

If you are running a thread that is equal to or more than corepoolsize, executor always prefers to join the request to the queue without adding a new thread .

If the request cannot be queued, a new thread is created unless the thread is created beyond maximumpoolsize, in which case the task is rejected.

Three types on the queue.

There are three common strategies for queuing:

submit directly. The default option for the work queue is synchronousqueue, which will submit tasks directly to the thread without maintaining them. Here, if there is no thread available to run the task immediately, attempting to join the task to the queue will fail, and a new thread will be constructed. This policy avoids locking when processing a set of requests that may have internal dependencies. Direct submissions typically require unbounded maximumpoolsizes to avoid rejecting newly submitted tasks. This policy allows the possibility of an increase in the number of lines that are allowed to continue when the command arrives in a row that exceeds the average that the queue can handle.

unbounded queues. using unbounded queues (for example, linkedblockingqueue that do not have a predefined capacity) will cause all corepoolsize threads to be busy while the newer tasks are waiting in the queue. This way, the created thread will not exceed corepoolsize. (therefore, the value of the maximumpoolsize is not valid.) When each task is completely independent of other tasks, that is, when task execution does not affect each other, it is appropriate to use a unbounded queue, for example, in a Web page server. This queueing can be used to handle transient burst requests, which allow the possibility of an increase in the number of lines that are allowed to occur when the command reaches an average of more than the queue can handle.

bounded queues. when using limited maximumpoolsizes, bounded queues (such as arrayblockingqueue) help prevent resource exhaustion, but may be difficult to adjust and control. The queue size and maximum pool size may need to be compromised: using large queues and small pools minimizes CPU usage, operating system resources, and context switching overhead, but can result in artificially reduced throughput. If tasks are frequently blocked (for example, if they are I/O boundaries), the system may schedule more threads than you permit. Using small queues typically requires a large pool size, high CPU utilization, but may encounter unacceptable scheduling overhead, which can also reduce throughput

Java multithreaded Development, executors, Futuretask, callable

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.