Home  >  Article  >  Java  >  Sample code analysis for in-depth understanding of Java ThreadPoolExecutor parameters

Sample code analysis for in-depth understanding of Java ThreadPoolExecutor parameters

黄舟
黄舟Original
2017-03-23 10:25:031852browse

This article mainly introduces relevant information for in-depth understanding of the parameters of Java ThreadPoolExecutor. Friends who need it can refer to

In-depth understanding of the parameters of Java ThreadPoolExecutor

1. Use Executors to create a thread pool

When creating threads before, I used the three methods of newFixedThreadPool(), newSingleThreadExecutor(), newCachedThreadPool() of Executors . Of course, Executors also use different parameters to new ThreadPoolExecutor

1. newFixedThreadPool()

Create a thread pool with a fixed number of threads. Since LinkedBlockingQueue is used, maximumPoolSize is useless. When corePoolSize is full, it is added to LinkedBlockingQueuequeue. Whenever a thread completes execution, take one from the LinkedBlockingQueue queue. So this is creating a fixed size thread pool.

 public static ExecutorService newFixedThreadPool(int nThreads) {
    return new ThreadPoolExecutor(nThreads, nThreads,
                   0L, TimeUnit.MILLISECONDS,
                   new LinkedBlockingQueue<Runnable>());
  }
 public ThreadPoolExecutor(int corePoolSize,
               int maximumPoolSize,
               long keepAliveTime,
               TimeUnit unit,
               BlockingQueue<Runnable> workQueue) {
   this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
       Executors.defaultThreadFactory(), defaultHandler);
  }

2.newSingleThreadPool()

Create a thread pool with a thread number of 1. Since LinkedBlockingQueue is used, maximumPoolSize is useless. A corePoolSize of 1 means that the number of threads is 1. When it is full, put it into the queue, and when the execution is completed, take one from the queue.

 public static ExecutorService newSingleThreadExecutor() {
    return new FinalizableDelegatedExecutorService
      (new ThreadPoolExecutor(1, 1,
                  0L, TimeUnit.MILLISECONDS,
                  new LinkedBlockingQueue<Runnable>()));
  }

3.newCachedThreadPool()

Create a bufferable thread pool. No size limit. Since the corePoolSize is 0, the task will be put into the SynchronousQueue queue. SynchronousQueue can only store a size of 1, so a new thread will be started immediately. Since the maximumPoolSize is Integer.MAX_VALUE, the size can be considered to be 2147483647. Limited by memory size.

public static ExecutorService newCachedThreadPool() {
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                   60L, TimeUnit.SECONDS,
                   new SynchronousQueue<Runnable>());
  }
public ThreadPoolExecutor(int corePoolSize,
             int maximumPoolSize,
             long keepAliveTime,
             TimeUnit unit,
             BlockingQueue<Runnable> workQueue) {
    this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
       Executors.defaultThreadFactory(), defaultHandler);
  }

2. Use ThreadPoolExecutor to create a thread pool

Constructor of ThreadPoolExecutor

 public ThreadPoolExecutor(int corePoolSize,
               int maximumPoolSize,
               long keepAliveTime,
               TimeUnit unit,
               BlockingQueue<Runnable> workQueue,
               ThreadFactory threadFactory,
               RejectedExecutionHandler handler) {
    if (corePoolSize < 0 ||
      maximumPoolSize <= 0 ||
      maximumPoolSize < corePoolSize ||
      keepAliveTime < 0)
      throw new IllegalArgumentException();
    if (workQueue == null || threadFactory == null || handler == null)
      throw new NullPointerException();
    this.corePoolSize = corePoolSize;
    this.maximumPoolSize = maximumPoolSize;
    this.workQueue = workQueue;
    this.keepAliveTime = unit.toNanos(keepAliveTime);
    this.threadFactory = threadFactory;
    this.handler = handler;
  }

Parameters:

                                                                                                                              CorePoolSize The number of core threads. When the number of threads                                                                                         maximumPoolSize, the maximum number of core threads. When the number of threads > = corePoolSize, the runnable will be put into the workQueue中

3. keepAliveTime Keep alive time, when the number of threads is greater than corePoolSize, the maximum time that an idle thread can keep.

4. unit time unit

5. workQueue holds the blocking queue of tasks

6. threadFactory creates a thread factory

7. handler rejection strategy

Task execution sequence:

1. When the number of threads is less than corePoolSize, create a thread to execute the task.

2. When the number of threads is greater than or equal to corePoolSize and the workQueue is not full, put it into the workQueue

3. The number of threads is greater than or equal to corePoolSize and when the workQueue is full, a new thread is created for the new task to run. The total number must be less than maximumPoolSize

4. When the total number of threads is equal to maximumPoolSize and the workQueue is full, the rejectedExecution of the handler is executed. That is the rejection strategy.

ThreadPoolExecutor has four rejection policies by default:

1. ThreadPoolExecutor.AbortPolicy() Directly

throws an exceptionRejectedExecutionException

2. ThreadPoolExecutor.CallerRunsPolicy() Directly calls the run method and blocks execution

3. ThreadPoolExecutor.DiscardPolicy() Directly discards subsequent tasks

4. ThreadPoolExecutor.DiscardOldestPolicy() Discards the head of the queue Of course, you can

inherit

RejectedExecutionHandler to write the rejection strategy.

##

int corePoolSize = 1;
 int maximumPoolSize = 2;
 int keepAliveTime = 10;
// BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<Runnable>();
 BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<Runnable>(5);
 ThreadFactory threadFactory = Executors.defaultThreadFactory();
 //线程池和队列满了之后的处理方式
 //1.跑出异常
 RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy(); 
 RejectedExecutionHandler handler2 = new ThreadPoolExecutor.CallerRunsPolicy();
 RejectedExecutionHandler handler3 = new ThreadPoolExecutor.DiscardPolicy();
 RejectedExecutionHandler handler4 = new ThreadPoolExecutor.DiscardOldestPolicy();

 
 ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, 
 TimeUnit.SECONDS, workQueue, threadFactory, handler2);
 
 
 for (int j = 1; j < 15; j++) {
  threadPoolExecutor.execute(new Runnable() {
  
  public void run() {
   
   try {
   System.out.println(Thread.currentThread().getName());
   TimeUnit.SECONDS.sleep(1);
   } catch (InterruptedException e) {
   e.printStackTrace();
   }
   
   
  }
  });
 }
 
 System.out.println(threadPoolExecutor);
 
 }

The above is the detailed content of Sample code analysis for in-depth understanding of Java ThreadPoolExecutor parameters. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn