Thread pool core: Three methods, seven parameters, four rejection policies

Pooling technology:

  • The essence of the program running: occupy the resources of the system! To optimize resource usage, consider using pooling techniques
  • Pooling technology: Prepare some resources in advance. If someone wants to use them, come here and take them back to me after using them

Benefits of thread pools:

  • Reduce resource consumption
  • Improve response speed
  • Convenient management

Thread reuse, can control the maximum number of concurrent management threads

Alibaba Java Development manual for thread pool generation is as follows:

Three ways to create a thread pool

public class ExecutorDemo {
    public static void main(String[] args) throws InterruptedException {
        // Single thread pool
        ExecutorService threadPool = Executors.newSingleThreadExecutor();
        // Create a thread pool of fixed size
        ExecutorService threadPool1 = Executors.newFixedThreadPool(5);
        // Scalable thread pool
        ExecutorService threadPool2 = Executors.newCachedThreadPool();
        System.out.println("Single thread pool");
        for (int i = 0; i <10 ; i++) {
            threadPool.execute(()->{
                System.out.println(Thread.currentThread().getName()+" ok");
            });
        }
        TimeUnit.SECONDS.sleep(2);
        System.out.println("Fixed size thread pool");
        for (int i = 0; i <10 ; i++) {
            threadPool1.execute(()->{
                System.out.println(Thread.currentThread().getName()+" ok");
            });
        }
        TimeUnit.SECONDS.sleep(2);
        System.out.println("Auto-sizing thread pools");
        for (int i = 0; i <10 ; i++) {
            threadPool2.execute(()->{
                System.out.println(Thread.currentThread().getName()+" ok"); }); }}}Copy the code

The result is as follows: a single thread pool has only one thread, a fixed size pool has a fixed number of threads, and a capacity adaptive pool does not mean that a few loops will create several threads.

A single thread pool pool-1-thread-1 OK pool-1-thread-1 OK pool-1-thread-1 OK pool-1-thread-1 OK pool-1-thread-1 OK pool-1-thread-1 OK Pool-1-thread-1 ok pool-1-thread-1 OK pool-1-thread-1 OK pool-1-thread-1 OK pool-1-thread-1 OK Pool-2-thread-2  ok pool-2-thread-3 ok pool-2-thread-4 ok pool-2-thread-1 ok pool-2-thread-1 ok pool-2-thread-2 ok pool-2-thread-4 ok Pool-2-thread-5 OK pool-2-thread-1 OK Pool-3-thread-1 OK pool-3-thread-2 OK pool-3-thread-3 OK pool-3-thread-1 ok pool-3-thread-2 ok pool-3-thread-4 ok pool-3-thread-6 ok pool-3-thread-7 ok pool-3-thread-5 ok pool-3-thread-1 okCopy the code

The seven parameters of the thread pool

public static ExecutorService newSingleThreadExecutor(a) {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1.1.0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
}
 public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
}
 public static ExecutorService newCachedThreadPool(a) {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
}
// The essence of all three methods is to call ThreadPoolExecutor
public ThreadPoolExecutor(intCorePoolSize, // Core thread pool size, minimum number of threads to holdintMaximumPoolSize, // Maximum core thread pool sizelongKeepAliveTime, // Idle thread lifetime, during which a thread is not processing any requests, BlockingQueue<Runnable> workQueue, // block queue ThreadFactory ThreadFactory, // ThreadFactory, RejectedExecutionHandler Handler) {	// Reject the policy
        if (corePoolSize < 0 ||
            maximumPoolSize <= 0 ||
            maximumPoolSize < corePoolSize ||
            keepAliveTime < 0)
            throw new IllegalArgumentException();
        if (workQueue == null || threadFactory == null || handler == null)
            throw new NullPointerException();
        this.acc = System.getSecurityManager() == null ?
                null :
                AccessController.getContext();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
}
Copy the code

Three or four refusal strategies

New ThreadPoolExecutor. AbortPolicy () / / bank full, and people come in, don't deal with, An exception is thrown new ThreadPoolExecutor. CallerRunsPolicy () / / where to go, general is given priority to the main thread to invoke the thread pool, So back to the main thread main processing of new ThreadPoolExecutor. DiscardPolicy () / / queue is full, the loss of task new ThreadPoolExecutor. DiscardOldestPolicy () / / queue is full, Try to compete with the earliest thread without throwing an exceptionCopy the code

Create a thread pool manually

How to define the maximum number of threads 1, CPU intensive computer is a few cores, is how many, can maintain the CPU efficiency of the highest 2, IO intensive judgment program is very consume IO threads, generally set to its twiceCopy the code
int num = Runtime.getRuntime().availableProcessors();
System.out.println("Computer cores:"+num);
Copy the code
public class ThreadPoolExecutorDemo {
    public static void main(String[] args) {
        // Custom thread pool
        // Scenario simulation, now the bank has a maximum of five counters, usually only two counters are working, this is the core thread number, there are three chairs in the waiting area,
        // This is a blocking queue. If three slots in the waiting area are full, the other three Windows that are not in use will open
        // It is also full, and the guest area is also full at the same time, at this time there is still someone in the door will trigger the rejection policy, according to the different rejection policy processing
        ExecutorService myPool = new ThreadPoolExecutor(
                2.5.1,
                TimeUnit.SECONDS,
                new LinkedBlockingDeque<>(3),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy()	// When the bank is full, someone else comes in, does not handle it, throws an exception
        );
        try {
            // Maximum load: blocking queue + maximum number of core threads
            // The current thread can handle 8, but 9 does not necessarily throw an exception, maybe the previous thread is finished, the ninth thread can handle
            // Too many threads can cause problems
            for (int i = 1; i <=9 ; i++) {
                myPool.execute(()->{
                    System.out.println(Thread.currentThread().getName()+" ok"); }); }}catch (Exception e) {
            e.printStackTrace();
        } finally{ myPool.shutdown(); }}}Copy the code

Running results:

1, the first refused to Java. Util. Concurrent. RejectedExecutionException: Task gdut.hzh.pool.ThreadPoolExecutorDemo$$Lambda$1/1831932724@7699a589 rejected from java.util.concurrent.ThreadPoolExecutor@58372a00[Running, pool size = 5, active threads = 0, queued tasks = 0, Completed the tasks = 8] at gdut. HZH. Pool. ThreadPoolExecutorDemo. Main (ThreadPoolExecutorDemo. Java: 30) 2, the second rejection policies pool-1-thread-3 ok pool-1-thread-3 ok pool-1-thread-3 ok pool-1-thread-3 ok pool-1-thread-4 ok main ok pool-1-thread-1 ok pool-1-thread-2 ok pool-1-thread-5 okCopy the code