Java thread pool ExecutorService details and example code

  • 2020-05-19 04:47:06
  • OfStack

Java thread pool ExecutorService

1. The thread pool

1.1 when are thread pools used

The processing time of a single task is relatively short. The number of tasks that will need to be handled is large.

1.2 benefits of using thread pools

Reduce the time spent creating and destroying threads and the overhead of system resources. If you do not use thread pools, you may create a large number of threads that consume system memory and "overswitch".

2. ExecutorService and Executors

2.1 introduction

ExecutorService is an interface that inherits Executor,


public interface ExecutorService extend Executor{
}

Executor is also an interface that contains only one method:


public interface Executor {
  void execute(Runnable command);
}

The top interface for thread pools in Java is Excutor, but strictly speaking > > Exector is not a thread pool, but a tool to execute threads, real threads > The pool interface is ExecutorService.

3.Executors

It is a static factory class, it can produce different types of thread pool, part of the source code as follows:


public class Executors {
//newFixedThreadPool
public static ExecutorService newFixedThreadPool(int nThreads) {
    return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>());
}
//newCacheThreadPool
 public static ExecutorService newCachedThreadPool() {
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE,60L, TimeUnit.SECONDS,new SynchronousQueue<Runnable>());
  }
 //newScheduledThreadPool
  public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
    return new ScheduledThreadPoolExecutor(corePoolSize);
  }
  //newStringooo
}

Let's look at a specific example to illustrate the similarities and differences between them.


package thread;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;

/**
 * Created by yang on 16-7-11.
 */
public class Ch09_Executor {
  private static void run(ExecutorService threadPool) {
    for (int i = 1; i < 5; i++) {
      final int taskID=i;
      threadPool.execute(new Runnable() {
        @Override
        public void run() {
          for(int i=1;i<5;i++){
            try{
              Thread.sleep(20);
            }catch (InterruptedException e)
            {
              e.printStackTrace();
            }
            System.out.println(" The first "+taskID+" The second mission "+i+" Time to perform ");
          }
        }
      });
    }
    threadPool.shutdown();

  }

  public static void main(String[] args) {
    // Create can hold 3 A pool of threads 
    ExecutorService fixedThreadPool= Executors.newFixedThreadPool(3);
    // The size of the thread pool is dynamically allocated based on the tasks performed 
    ExecutorService cacheThreadPool=Executors.newCachedThreadPool();
    // Create a pool of threads for a single thread , If the current thread is suddenly interrupted while executing a task , Will create 1 Replace it with a new thread to continue execution .
    ExecutorService singleThreadPool=Executors.newSingleThreadExecutor();
    // The effect is similar to Timer The timer 
    ScheduledExecutorService scheduledThreadPool=Executors.newScheduledThreadPool(3);
    // run(fixedThreadPool); //(1)
    //run(cacheThreadPool); //(2)
    // run(singleThreadPool); //(3)
    // run(scheduledThreadPool); //(4)
  }
}

4. 4 common thread pools

4.1 CachedThreadPool

CachedThreadPool creates a cache, caches the initialized thread, terminates and removes threads that have not been used for 6 seconds from the cache.
If the thread is available, use the previously created thread. If the thread is not available, create a new thread.

Reuse:

Cache pool, first check if there are any previously established threads in the pool, if so, reuse, if not, create a new thread to join the pool,

Usage scenarios:

The cache pool is usually used to perform some asynchronous tasks with a short lifetime, so it is not used much in the connection-oriented Daemon type SERVER.

Timeout:

The thread that can reuse must be a pool thread within timeout IDLE. The default timeout is 60s. After this IDLE length, the thread instance will be terminated and the pool will be removed.

The end:

Threads that put CachedThreadPool in don't have to worry about ending, and if TIMEOUT is not active, it will be automatically terminated.

Example explanation:

Remove the comment of (2), run it, and the result is as follows:


 The first 1 The second mission 1 Time to perform 
 The first 3 The second mission 1 Time to perform 
 The first 2 The second mission 1 Time to perform 
 The first 4 The second mission 1 Time to perform 
 The first 3 The second mission 2 Time to perform 
 The first 1 The second mission 2 Time to perform 
 The first 2 The second mission 2 Time to perform 
 The first 4 The second mission 2 Time to perform 
 The first 3 The second mission 3 Time to perform 
 The first 1 The second mission 3 Time to perform 
 The first 2 The second mission 3 Time to perform 
 The first 4 The second mission 3 Time to perform 
 The first 3 The second mission 4 Time to perform 
 The first 2 The second mission 4 Time to perform 
 The first 4 The second mission 4 Time to perform 
 The first 1 The second mission 4 Time to perform 

As can be seen from the results, the four tasks were performed alternately.

4.2FixedThreadPool

In FixedThreadPool, there is a pool of a fixed size,

If the number of tasks that need to be executed exceeds the pool size, many of the outgoing tasks are in a waiting state until there is a free thread to execute the task.
If the task currently being performed is smaller than the pool size, the idle thread will not be destroyed.

Reuse:

fixedThreadPool is similar to cacheThreadPool, but it can be used as long as reuse, but it can't always build new threads

Fixed number

It is unique in that at any point in time, there can only be a fixed number of active threads, and if a new thread is to be created, it can only be placed in a different queue until one of the current threads terminates and is moved out of the pool

Timeout:

Unlike cacheThreadPool, FixedThreadPool has no IDLE mechanism

Usage scenarios:

Therefore, the majority of FixedThreadPool is for some very stable and fixed normal concurrent threads, mostly for servers

Source code analysis:

From the source code of the method, the cache pool and fixed pool call the same underlying pool, but with different parameters.
fixed pool has a fixed number of threads and is 0 seconds IDLE (no IDLE)
cache pool thread count supports 0-Integer.MAX_VALUE (apparently without considering the host's resource capacity at all), 60 seconds IDLE

Example explanation:

Remove the comment of (1) and the result is as follows:


 The first 1 The second mission 1 Time to perform 
 The first 3 The second mission 1 Time to perform 
 The first 2 The second mission 1 Time to perform 
 The first 1 The second mission 2 Time to perform 
 The first 3 The second mission 2 Time to perform 
 The first 2 The second mission 2 Time to perform 
 The first 1 The second mission 3 Time to perform 
 The first 3 The second mission 3 Time to perform 
 The first 2 The second mission 3 Time to perform 
 The first 1 The second mission 4 Time to perform 
 The first 3 The second mission 4 Time to perform 
 The first 2 The second mission 4 Time to perform 
 The first 4 The second mission 1 Time to perform 
 The first 4 The second mission 2 Time to perform 
 The first 4 The second mission 3 Time to perform 
 The first 4 The second mission 4 Time to perform 

Create a fixed size thread pool, the capacity is 3, and then loop to execute 4 tasks, from the output results can be seen that the first 3 tasks are completed, and then the idle thread to execute the fourth task.

4.3SingleThreadExecutor

What SingleThreadExector gets is a single thread that will ensure that your task is completed. Singleton thread, there can only be 1 thread in any time pool If the current thread terminates unexpectedly, a new thread is created to continue the task, which is different from creating a thread directly and newFixedThreadPool(1). You use the same underlying pool as the cache pool and fixed pool, but the number of threads is 1-1,0 seconds. IDLE (no IDLE)

Remove (3) comments. See the execution results as follows:


 The first 1 The second mission 1 Time to perform 
 The first 1 The second mission 2 Time to perform 
 The first 1 The second mission 3 Time to perform 
 The first 1 The second mission 4 Time to perform 
 The first 2 The second mission 1 Time to perform 
 The first 2 The second mission 2 Time to perform 
 The first 2 The second mission 3 Time to perform 
 The first 2 The second mission 4 Time to perform 
 The first 3 The second mission 1 Time to perform 
 The first 3 The second mission 2 Time to perform 
 The first 3 The second mission 3 Time to perform 
 The first 3 The second mission 4 Time to perform 
 The first 4 The second mission 1 Time to perform 
 The first 4 The second mission 2 Time to perform 
 The first 4 The second mission 3 Time to perform 
 The first 4 The second mission 4 Time to perform 

The four tasks are executed sequentially.

4.4 ScheduledThreadPool

ScheduledThreadPool is a fixed-size thread pool, similar to FixedThreadPool, that performs timed tasks.
The result obtained by removing the comment (4) is the same as that obtained by FixedThreadPool. ScheduledThreadPool's main function is not here, but the timing task. See the following example:


package thread;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * Created by yang on 16-7-11.
 */
public class MyScheduledTask implements Runnable {
  private String tname;
  public MyScheduledTask(String name){
    this.tname=name;
  }
  public void run(){
    System.out.println(tname+" Task time delay 2 Seconds to perform !");
  }

  public static void main(String[] args) {
    ScheduledExecutorService scheduledPool= Executors.newScheduledThreadPool(2);
    ScheduledExecutorService singSchedulePool=Executors.newSingleThreadScheduledExecutor();
    MyScheduledTask mt1=new MyScheduledTask("mt1");
    MyScheduledTask mt2=new MyScheduledTask("mt2");
    // In order to scheduledThreadPool Start the mt1 Task execution 
    scheduledPool.schedule(mt1,2, TimeUnit.SECONDS);
    // with singlescheduledthreadPool Start the mt2;
    singSchedulePool.schedule(mt2,2000,TimeUnit.MILLISECONDS);
    scheduledPool.shutdown();
    singSchedulePool.shutdown();
  }
}

Results:


mt1 Task time delay 2 Seconds to perform !
mt2 Task time delay 2 Seconds to perform !

After the program has been running for 2 seconds, the result will be displayed, indicating that the thread was executed after 2 seconds.

Thank you for reading, I hope to help you, thank you for your support of this site!


Related articles: