Java: Thread Pool Learning (1)

Java : Thread Pool Learning ( 1 ) :

I just finished the first draft of my graduation thesis recently, and now I finally have some time to write a blog.

Then let's take a look at the knowledge points of thread pools.

This article only talks about the construction methods of some commonly used thread pools. I will write about other aspects later (suddenly I found that the previous blogs were not very good, and I will pay attention to the format in the future).

 

Let's take a look at our commonly used:

Take a look at the four static methods in the Executors class that we may use more often :

public static ExecutorService newCachedThreadPool()

public static ExecutorService newFixedThreadPool(int nThreads)

public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize)

public static ExecutorService newSingleThreadExecutor()

 

Of course, they all have another overloaded method, which will be discussed later?

If you take a look at their source code, you will find that in the end they all lead to the following method (this method is in java.util.concurrent.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.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;
    }

The main parameters of the ThreadPoolExecutor constructor

Then let's take a look at his main attributes. In fact, God Doug has written it clearly in the comments, so I will translate it and blow water:

corePoolSize : the number of core threads (more on this later)

maximumPoolSize : the maximum number of threads allowed to be created

keepAliveTime: Can you guess its main function just by looking at the word? When the number of threads in the thread pool is greater than the number of core threads, the thread will be closed if there is no task to do it after the idle time exceeds this time. It will not be closed when it is less than or equal to the number of core threads, but it can be set to be closed through public void allowCoreThreadTimeOut( true ) .

TimeUnit unit: the time unit of keepAliveTime (for conversion)

this.keepAliveTime = unit.toNanos(keepAliveTime);

 

BlockingQueue<Runnable> workQueue : task queue

ThreadFactory threadFactory: The factory that generates threads. Another overloaded method has this parameter.

RejectedExecutionHandler handler: When the thread pool is full, but there are new tasks submitted, this strategy will be used for processing. Four implementation classes have been defined in ThreadPoolExecutor :

public static class AbortPolicy implements RejectedExecutionHandler

Throws RejectedExecuti onException directly , this is the default processing strategy.

public static class CallerRunsPolicy implements RejectedExecutionHandler

If the thread pool is not closed, it will be executed by the thread that submitted the task.

public static class DiscardOldestPolicy implements RejectedExecutionHandler

This strategy is to throw away the task waiting for the head of the queue, and then submit the new task to the waiting queue.

public static class DiscardPolicy implements RejectedExecutionHandler

Don't kill you, don't do anything.

 

Well, finished talking about the main parameters. Let's talk about the main ones:

newCachedThreadPool

public static ExecutorService newCachedThreadPool() {return new ThreadPoolExecutor(0, Integer.MAX_VALUE,60L, TimeUnit.SECONDS,new SynchronousQueue<Runnable>());}
    
                                  
                                  

After reading all of the above, you will know what to say here. The number of core threads is 0, the maximum number of threads is Integer.MAX_VALUE, the keepAliveTime is 60 seconds, and the task queue uses SynchronousQueue.

This thread pool will perform better when tasks can be completed quickly. If a thread has been idle for 60 seconds with no tasks, the thread will be shut down and removed from the thread pool. As all threads will be shut down, the entire thread pool will not take up any system resources, so it will not be a problem if the thread pool is idle for a long time.

SynchronousQueue is a special BlockingQueue, it does not store any elements, it has a virtual queue, regardless of read operation or write operation, if the current queue stores threads in the same mode as the current operation, then the current operation also enters the queue to wait; If it is the opposite mode, the pairing is successful, and the head node is taken from the current queue.

This article is not too in-depth for the time being, maybe I will add more in a follow-up article.

 

newFixedThreadPool

public static ExecutorService newFixedThreadPool(int nThreads) {

return new ThreadPoolExecutor(nThreads, nThreads,

                                   0L , TimeUnit. MILLISECONDS , new LinkedBlockingQueue<Runnable>());}
                                  

The number of core threads is nThreads ( specified by the parameter ) , the maximum number of threads is nThreads , the keepAliveTime is 0 seconds, and the task queue adopts LinkedBlockingQueue .

LinkedBlockingQueue is a blocking queue implemented based on a singly linked list.

 

newSingleThreadExecutor

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

                                
                                

The number of core threads is 1, the maximum number of threads is 1, the keepAliveTime is 0 seconds, and the task queue adopts LinkedBlockingQueue .

 

newScheduledThreadPool

public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {return new ScheduledThreadPoolExecutor(corePoolSize);}
    

public ScheduledThreadPoolExecutor(int corePoolSize) {super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,new DelayedWorkQueue());}
    
          

The number of core threads is corePoolSize ( specified by the parameter ) , the maximum number of threads is Integer.MAX_VALUE, the keepAliveTime is 0 seconds, and the task queue adopts DelayedWorkQueue.

 

Well, this one will come here first. The specific implementation process will be written in detail later in my blog. . . Big guys are welcome to click ( sao) and comment (rao).

 

 

 

 

 

 

 

 

 

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325765388&siteId=291194637