编程知识 cdmana.com

Java thread pool

java Pooling technology in can be prepared for us before we open up new threads , This reduces the overhead of the system . Thread pool helps us manage threads in a unified way , It also improves the response of the system .jdk concurrent Medium Executors Class gives us a way to create a thread pool , Simple and easy to use . There are mainly the following methods :

  1. newFixedThreadPool(int nThreads) Thread pool with fixed number of threads ;
  2. newSingleThreadExecutor() A thread pool that produces only a single thread ;
  3. newCachedThreadPool Cache type thread pool , The number of threads is scalable , Not fixed ;

Let's start with , In addition to these jdk Give us a packaged method , We can create our own thread pool manually , Self creation can deepen our impression of this part of knowledge , We can do it by calling ThreadPoolExecutor To create :

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), defaultHandler);
    }

Take a look at his overloaded constructor :

    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;
    }

In its construction method , There are several important parameters :

  1. corePoolSize Number of core threads in thread pool ;
  2. maximumPoolSize The maximum number of threads in the thread pool ;
  3. keepAliveTime Idle thread inventory time , Beyond this time, it will be recycled ( More than the number of core threads );
  4. unit Time unit ;
  5. workQueue Blocking queues , When the number of threads exceeds the number of core threads , The task will be put in the queue ;
  6. threadFactory Thread factory , Used to create threads , The default inner class is used ,ThreadPoolExecutor There is no setter/getter Method ;
  7. handler Refusal strategy , When the blocking queue is full , And when the maximum number of threads is exceeded , Will implement the rejection strategy reject Method .

    Take a look at the thread of thread execution in thread pool execute Method :

    public void execute(Runnable command) {
        if (command == null)
            throw new NullPointerException();
            
        int c = ctl.get();
        //  If the number of worker threads is less than the number of core threads , call  addWorker  Method and return directly to 
        if (workerCountOf(c) < corePoolSize) {
            if (addWorker(command, true))
                return;
            c = ctl.get();
        }
        //  Exceeded the number of core threads , Priority added to blocking queue 
        if (isRunning(c) && workQueue.offer(command)) {
            int recheck = ctl.get();
            if (! isRunning(recheck) && remove(command))
                reject(command);
            //  The blocking queue is full , New thread ( Every thread is a  worker) To add to  workers.
            else if (workerCountOf(recheck) == 0)
                addWorker(null, false);
        }
        //  The blocking queue is full , And the number of threads is greater than the maximum number of threads , call  handler  Of  rejectedExecution  Method .
        else if (!addWorker(command, false))
            reject(command);
    }

Let's look at the rejection strategy of the thread pool ,ThreadPoolExecutor, There's a property defaultHandler, The default rejection strategy . The type is AbortPolicy: Its rejectedExecution The method is to throw an exception .

public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            throw new RejectedExecutionException("Task " + r.toString() +
                                                 " rejected from " +
                                                 e.toString());
        }

DiscardPolicy: Don't do anything? , Give up this mission

        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
        }

DiscardOldestPolicy: Abandon the task ahead , Add new tasks to the cache queue :

public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            if (!e.isShutdown()) {
                //  Pop up the top task 
                e.getQueue().poll();
                //  Perform new tasks 
                e.execute(r);
            }
        }

CallerRunsPolicy: Executed by the calling thread run Method :

        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            if (!e.isShutdown()) {
                //  As you can see, only the current thread called  run  Method , There is no new thread .
                r.run();
            }
        }

Summary :

 This paper mainly introduces the creation methods of thread pool 、ThreadPoolExecutor  The constructor and the meaning of the seven parameters , At the same time, it also expounds the function and principle of four rejection strategies .

版权声明
本文为[Friends]所创,转载请带上原文链接,感谢

Scroll to Top