Executor线程池扩展

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/cdw8131197/article/details/62893869

线程池杂记,想到哪就写到哪了。

线程池的种类

new FixedThreadPool
new SingleThreadExecutor
new CachedThreadPool
new ScheduledThreadPool

分析:newFixedThreadPool

JDK源码:

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

从两段源码中可以看出:
corePoolSize == maximumPoolSize,所以称之为固定大小线程池
keepAliveTime 是默认值0
任务队列为无序阻塞队列:LinkedBlockingQueue<Runnable>
线程工厂:默认工程
线程池拒绝策略:默认拒绝策略

分析:SingleThreadExecutor

JDK源码:

    public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>(),
                                    threadFactory));
    }
    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             threadFactory, defaultHandler);
    }

从两段源码中可以看出:
与固定线程池区别,SingleThreadExecutor给出默认线程size为1,当线程出现问题挂起时,会新建另一个线程,线程池中始终保持有一个线程

分析:CachedThreadPool

JDK源码:

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

这个线程池默认大小即corePoolSize为0,当没有任务时,在线程池中没有线程。
队列:SynchronousQueue<Runnable>()
此队列的特点是长度为0,队列中不会存储任务work,它的目的是交换任务work,即当线程池从队列拿去任务时,恰好是向队列中放置任务霎间。当有任务时会创建新的线程,线程超过60秒没有用则会被终结。
这种也称之为线程池的直接提交策略。这种策略需要线程具有无限增长的能力。

线程池扩展方法

当线程在执行前需要执行某任务,或线程执行完成后需要执行某任务时,我们可扩展线程池方法beforeExecutor(),afterExecutor()等

示例如下:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class ThreadPoolTest {

    /**
     * @param args
     * @throws InterruptedException 
     */
    public static void main(String[] args){
        // TODO Auto-generated method stub

            ExecutorService es = new ThreadPoolExecutor(3, 3,
                    0L, TimeUnit.MILLISECONDS,
                    new LinkedBlockingQueue<Runnable>(),
                    Executors.defaultThreadFactory()){
                @Override
                protected void beforeExecute(Thread t, Runnable r) {
                    // TODO Auto-generated method stub
                    super.beforeExecute(t, r);
                    System.out.println("执行之前");
                }
                @Override
                protected void afterExecute(Runnable r, Throwable t) {
                    // TODO Auto-generated method stub
                    super.afterExecute(r, t);
                    System.out.println("执行之后");
                }
            };
//          ExecutorService es = Executors.newCachedThreadPool();
            for(int i=0;i<10;i++){
                final int task =i;
                es.execute(new Runnable() {
                    @Override
                    public void run() {
                        // TODO Auto-generated method stub
                        for(int j=0;j<10;j++){
                            System.out.println(Thread.currentThread().getName()+"---loop--"+j+"---task--"+task);
                            try {
                                Thread.sleep(1000);
                            } catch (InterruptedException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                        }
                    }
                });
            }
    }

}

线程池的拒绝策略使用方式如下:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class ThreadPoolTest {

    /**
     * @param args
     * @throws InterruptedException 
     */
    public static void main(String[] args){
        // TODO Auto-generated method stub

            ExecutorService es = new ThreadPoolExecutor(3, 3,
                    0L, TimeUnit.MILLISECONDS,
                    new LinkedBlockingQueue<Runnable>(3),
                    Executors.defaultThreadFactory(),
                    new RejectedExecutionHandler() {
                        @Override
                        public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
                            // TODO Auto-generated method stub
                            System.out.println("任务被丢弃");    
                        }
                    })
//          ExecutorService es = Executors.newCachedThreadPool();
            for(int i=0;i<10;i++){
                final int task =i;
                es.execute(new Runnable() {
                    @Override
                    public void run() {
                        // TODO Auto-generated method stub
                        for(int j=0;j<10;j++){
                            System.out.println(Thread.currentThread().getName()+"---loop--"+j+"---task--"+task);
                            try {
                                Thread.sleep(1000);
                            } catch (InterruptedException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                        }
                    }
                });
            }
    }

}

给出固定线程池和指定的任务队列,当线程池中线程数达到最大并且任务队列满时,有新执行任务时,任务将会执行指定的拒绝策略

猜你喜欢

转载自blog.csdn.net/cdw8131197/article/details/62893869