Basic use of Java Thread Pool

Source: Internet
Author: User

Basic use of Java Thread Pool

Threads play an important role in both Java Development and Android development. Today we will talk about the thread pool.

I. Thread Pool Overview

In Android development, we often put a time-consuming task in a thread for execution to avoid ANR exceptions. However, if we enable multithreading on a page and the thread finishes execution in a short period of time, we can frequently create threads to reduce the system running efficiency. So there is a thread pool.What is the role of the thread pool?
The thread pool automatically or manually configures the number of threads in a thread pool based on system environment variables, so that the creation and recycling of threads can reach an ideal state, reducing the consumption of system resources, improve system efficiency. In this way, we have obtained several advantages of using the thread pool:

Reduce resource consumption. By reusing the created threads to reduce the consumption caused by thread creation and destruction, the thread pool is used to manage the threads, improving the system's endurance. (Each thread requires 1 MB of memory ). Increase the response speed. When a task arrives, the task can be executed immediately without waiting for the thread to be created. 2. Basic usage of the thread pool

In jdk1.5, java provides us with the java. util. concurrent package, which contains the interfaces and classes used for our thread pool. The top-level interface of the thread pool is the Executor interface. It has an execute (Runnable) method used to execute the submitted Runnable task. It is just an interface, so you need to have its implementation body:

Configuring the thread pool is a complicated task. If we do not know the principle of the thread pool well, it is easy to cause the configured thread pool to fail. Therefore, the system provides the Executors class, which provides some static methods to help us create some common thread pools.

Public static ExecutorService newFixedThreadPool (int nThreads): Create a thread pool with a fixed number of threads. Each time a task is submitted, a thread is created until the thread reaches the maximum size of the thread pool. The size of the thread pool remains unchanged once it reaches the maximum value. If a thread ends due to an execution exception, the thread pool will add a new thread. Public static ExecutorService newCachedThreadPool (): Create a cacheable thread pool. If the thread pool size exceeds the thread required to process the task, some Idle threads (not executed in 60 seconds) will be reclaimed. When the number of tasks increases, this thread pool can intelligently add new threads to process tasks. This thread pool does not limit the thread pool size. The thread pool size depends entirely on the maximum thread size that can be created by the operating system (or JVM. Public static ScheduledExecutorService newScheduledThreadPool (int corePoolSize): Create a thread pool that supports scheduled and periodic task execution. In most cases, it can be used to replace the Timer class. Public static ExecutorService newSingleThreadExecutor (): Create a single-threaded thread pool. This thread pool only has one thread working, which is equivalent to a single thread serial execution of all tasks. If this unique thread ends due to an exception, a new thread will replace it. This thread pool ensures that all tasks are executed in the order they are submitted.

Test Case:

We create a Text thread for testing:

    class Text implements Runnable{        String name;        public Text(String name){            this.name = name;        }        @Override        public void run() {            System.out.println(Thread.currentThread().getName() + "--" + name);        }    }

Now let's test the effect of the thread pool:

1. ExecutorService newFixedThreadPool (int nThreads) creates a specified number of thread pools.
Public static void main (String [] args) {// we create a thread pool named 3 ExecutorService exServiceFixed = Executors. newFixedThreadPool (3); Text t1 = new Text ("t1"); Text t2 = new Text ("t2"); Text t3 = new Text ("t3 "); text t4 = new Text ("t4"); Text t5 = new Text ("t5"); exServiceFixed.exe cute (t1); exServiceFixed.exe cute (t2); exServiceFixed.exe cute (t3 ); exServiceFixed.exe cute (t4); exServiceFixed.exe cute (t5); exServiceFixed. shutdown ();}

Result:

    pool-1-thread-1--t1    pool-1-thread-1--t4    pool-1-thread-1--t5    pool-1-thread-2--t2    pool-1-thread-3--t3

We can see that although we have used the thread pool to execute five thread tasks, there are only three threads in the thread pool that we specified to be working, which improves the efficiency.

2. ExecutorService newCachedThreadPool () creates a reusable thread pool with no specified size
Public static void main (String [] args) {// we create a reusable thread pool ExecutorService exServiceCached = Executors. newCachedThreadPool (); Text t1 = new Text ("t1"); Text t2 = new Text ("t2"); Text t3 = new Text ("t3 "); text t4 = new Text ("t4"); Text t5 = new Text ("t5"); exServiceCached.exe cute (t1); exServiceCached.exe cute (t2); exServiceCached.exe cute (t3 ); exServiceCached.exe cute (t4); exServiceCached.exe cute (t5); exServiceCached. shutdown ();}

Running result:

    pool-1-thread-1--t1    pool-1-thread-2--t2    pool-1-thread-3--t3    pool-1-thread-4--t4    pool-1-thread-5--t5

There are five threads in the thread pool. This thread pool is reusable and does not limit the size. The number of threads is determined by the size that can be created by JVM in the system.

3. ScheduledExecutorService newScheduledThreadPool (int corePoolSize) creates a scheduled thread pool.

For example:

Public static void main (String [] args) {// we create a reusable thread pool ScheduledExecutorService scheduledExecutorService = Executors. newScheduledThreadPool (2); Text t1 = new Text ("t1"); Text t2 = new Text ("t2"); Text t3 = new Text ("t3 "); text t4 = new Text ("t4"); Text t5 = new Text ("t5"); scheduledExecutorService. schedule (t1, 2000, TimeUnit. MILLISECONDS); scheduledExecutorService. schedule (t2, 2000, TimeUnit. MILLISECONDS );}

Note: The ScheduledExecutorService used in this case is the implementation interface of the ExecutorService interface. The schedule method is used to schedule a task. The thread executes the task after the specified time.

In addition, it also has scheduled and continuous tasks,

    scheduledExecutorService.scheduleAtFixedRate(t1, 1000,2000, TimeUnit.MILLISECONDS);    scheduledExecutorService.scheduleAtFixedRate(t2, 1000,2000, TimeUnit.MILLISECONDS);    scheduledExecutorService.scheduleWithFixedDelay(t1, 1000,2000, TimeUnit.MILLISECONDS);

Execute tasks at intervals.

    pool-1-thread-2--t1    pool-1-thread-1--t2    pool-1-thread-2--t1    pool-1-thread-1--t2    pool-1-thread-2--t1    pool-1-thread-1--t2    pool-1-thread-2--t1    pool-1-thread-1--t2    pool-1-thread-2--t1    pool-1-thread-2--t2    pool-1-thread-2--t1    pool-1-thread-1--t2    pool-1-thread-2--t1    pool-1-thread-1--t2    pool-1-thread-2--t1    pool-1-thread-1--t2    pool-1-thread-2--t1    pool-1-thread-1--t2
4. ExecutorService newSingleThreadExecutor
Public static void main (String [] args) {// we create a reusable thread pool ExecutorService executorServiceSingle = Executors. newSingleThreadExecutor (); Text t1 = new Text ("t1"); Text t2 = new Text ("t2"); Text t3 = new Text ("t3 "); executorServiceSingle.exe cute (t1); executorServiceSingle.exe cute (t2); executorServiceSingle.exe cute (t3 );}

Result:

    pool-1-thread-1--t1    pool-1-thread-1--t2    pool-1-thread-1--t3

We can see that only one thread is executing our task.

Iii. Supplementary knowledge of Thread Pool

Here, we will add the ExecutorService. submit () method. This method has three reloads:

Future submit (Callable task); Future submit (Runnable task, T result); Future
    public interface Callable
  
    {        /**         * Computes a result, or throws an exception if unable to do so.         *         * @return computed result         * @throws Exception if unable to compute a result         */        V call() throws Exception;    }
  

The call () method is used to calculate a result based on the annotation.

Source code structure of ure:

    public interface Future
  
    {        boolean cancel(boolean mayInterruptIfRunning);        boolean isCancelled();        boolean isDone();        V get() throws InterruptedException, ExecutionException;        V get(long timeout, TimeUnit unit)            throws InterruptedException, ExecutionException, TimeoutException;    }
  

Five methods are defined in the Future interface. The following explains the role of each method in sequence:

The cancel method is used to cancel a task. if the task is canceled successfully, true is returned. If the task fails to be canceled, false is returned. The mayInterruptIfRunning parameter indicates whether to cancel a task in progress but not completed. If it is set to true, the task in progress can be canceled. If the task has been completed, no matter whether mayInterruptIfRunning is true or false, false is returned for this method, that is, false is returned if the task has been canceled; if the task is being executed, if mayInterruptIfRunning is set to true, true is returned. If mayInterruptIfRunning is set to false, false is returned. If the task has not been executed, true is returned regardless of whether mayInterruptIfRunning is true or false. The isCancelled method indicates whether the task is successfully canceled. if the task is successfully canceled before it is completed, true is returned. The isDone method indicates whether the task has been completed. if the task is completed, true is returned. The get () method is used to obtain the execution result. This method is blocked and will not be returned until the task is completed;

Get (long timeout, TimeUnit unit) is used to obtain the execution result. If no result is obtained within the specified time, null is returned directly.
That is to say, Future provides three functions:

1) Determine whether the task is completed;

2) the task can be interrupted;

3) obtain the task execution result.

Because Future is only an interface, it cannot be used directly to create objects. Therefore, the following FutureTask is available.

It is not complicated either. Several methods are used to determine whether the task is finished or not, and get the result of the task through the get method. Let's look at an example!

Public class MainDemo {public static void main (String [] args) {// we create a reusable thread pool ExecutorService executorServiceSingle = Executors. newSingleThreadExecutor (); Future
  
   
Future = executorServiceSingle. submit (new AddCallable (); try {System. out. println (future. get ();} catch (InterruptedException e) {e. printStackTrace ();} catch (ExecutionException e) {e. printStackTrace () ;}} class AddCallable implements Callable
   
    
{@ Override public Integer call () throws Exception {// execute our business logic processing return 2 + 3 ;}}
   
  

We implement a Callable interface to process our tasks, and then use Future to obtain the task results. If the Executor background thread pool has not completed Callable calculation, this call returns the get () method of the Future object, blocking until the calculation is complete. This is why InterruptedException exceptions need to be captured. Is this similar to our Android download task. Start a download task and process it in UIThread sent by Handler.

There is also a combination of Callable + FutureTask

    Task task = new Task();    FutureTask
  
    futureTask = new FutureTask
   
    (task);    Thread thread = new Thread(futureTask);    thread.start();
   
  
Iv. Summary

Based on the principles of reviewing knowledge points, we have not introduced the configuration of thread pools. You can search for relevant materials to learn and review this knowledge point, this is a simple framework used to write an Android network request over the past few days. Therefore, the knowledge points also give a brief introduction to usage, and the detailed in-depth analysis is not done.

Related Article

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.