Java线程池

2020-05-23  本文已影响0人  longLiveData

1.什么是线程池

java.util.concurrent.Executors 类中提供了很多方法来创建线程池。

在代码的开头的注释上就写明了,它可以创建重复使用固定数量线程的线程池,如果在所有线程都处于活动状态时提交了其他任务,那么他们将在队列中等待线程可用。

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

而创建线程池就是为了解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力。

做Java的,当然知道线程池,我们在做开发的时候有时候需要做的任务慢慢的增多,复杂性也会变得越来越强,所以线程的个数就会一点点的往上增加,而对应的线程占用的资源也就越来越多,多个线程占用资源的释放与注销需要维护,这时候多个线程的管理就显得有尤为重要。针对这一情况,sun公司提供了线程池,对线程集合的管理工具,所以线程池就出现了。

2.常见的线程池都有哪些,使用的场景是哪里呢?

这时候这个java.util.concurrent.Executors 类就排上用场了,比如:

(1) newSingleThreadExecutor

// 单个线程的线程池,即线程池中每次只有一个线程工作,单线程串行执行任务
public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             threadFactory, defaultHandler);
    }

(2) newFixedThreadPool

下面的两个方法是这个方法的重载,而它的意思很明确,建立一个线程数量固定的线程池,规定的最大线程数量,超过这个数量之后进来的任务,会放到等待队列中,如果有空闲线程,则在等待队列中获取,遵循先进先出原则。

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

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

(3) newCacheThreadExecutor

缓存型线程池,这个线程池的意思是在核心线程达到最大值之前,如果继续有任务进来就会创建新的核心线程,并加入核心线程池,即使有空闲的线程,也不会复用。

而达到最大核心线程数后,新任务进来,如果有空闲线程,则直接拿来使用,如果没有空闲线程,则新建临时线程.

而缓存型的线程池使用的是SynchronousQueue作为等待队列,他不保存任何的任务,新的任务加入进来之后,他会创建临时线程来进行使用

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

(4) newScheduledThreadPool

计划型线程池,在它的注释中给出的很明确的解释,创建一个线程池,该线程池可以计划在给定的延迟,或周期性地执行。

也就是说,在新任务到达的时候,我们看到底有没有空闲线程,如果有,直接拿来使用,如果没有,则新建线程加入池。而这里面使用的就是DelayedWorkQueue作为等待队列,中间进行了一定的等待,等待时间过后,继续执行任务。

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

3. 阿里巴巴Java开发手册对线程是怎么说的?

我们在日常使用都是会出现这段代码:

ExecutorService cachedThreadPool=Executors.newFixedThreadPool();

阿里巴巴Java开发手册中,强制线程池不允许使用 Executors 去创建

推荐使用 ThreadPoolExecutor

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

这个方法里面有几个参数

上一篇 下一篇

猜你喜欢

热点阅读