java中Executors创建线程池的三种方法

三个关键线程池的比较

1、创建单个线程(单例模式)

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

由于调用的ThreadPoolExecutor的构造方法的核心池大小和最大线程池均为1,所以该线程池只能存在一个线程。

2、创建固定大小的线程池

public static ExecutorService newFixedThreadPool(int nThreads) {
    return new ThreadPoolExecutor(nThreads, nThreads,
                                  0L, TimeUnit.MILLISECONDS,
                                  new LinkedBlockingQueue<Runnable>());
}

我们可以看到,该创建线程池的方法提供了一个课传递的参数nThreads,该参数可以设置线程池的核心大小以及最大容量,即该线程池的固定大小。

3、可以伸缩的线程池

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

我们可以看到,这里的最大线程大小可以达到Integer的最大大小2147483647,一般情况下我们是用不了这么多线程的,想用这么多的线程,是需要强大的硬件设备的支持,我们可以看到在线程被创建后60s如果没有被调用就会被释放,关于这些参数我会在后面讲到。

这几种方式创建的线程池都是通过创建ThreadPoolExecutor对象来实现的

4、ThreadPoolExecutor

我们来看一下这三个线程池创建时调用的ThreadPoolExecutor的构造方法

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

我们看下这里面调用的this方法

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

所以我们看到这些方法本质上都是调用了ThreadPoolExecutor的构造方法

注意:虽然用Executors创建线程池可以方便我们的操作,但是阿里发布的 Java开发手册中强制线程池不允许使用 Executors 去创建,所以建议大家还是用ThreadPoolExecutor 来创建线程池

ThreadPoolExecutor创建线程池参考https://blog.csdn.net/jjj___jjj/article/details/105314542

你可能感兴趣的:(java多线程,java,多线程,并发编程)