线程池探索之基础篇

线程池探索之基础篇

  • 一、使用线程池的好处

  • 二、线程池的内部实现

  • 三、线程池的工厂类

一、使用线程池的好处:

    
1)重用线程,避免系统频繁地创建和销毁线程

    
2)任务过多时,通过排队避免创建过多线程,减少系统资源的消耗

阿里开发手册中规定:线程资源必须通过线程池提供,不允许在应用中自行显式创建线程。

二、线程池的内部实现:

JDK中线程池的实现类是ThreadPoolExecutor,先来看看其最重要的构造方法:

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler)
 


线程池探索之基础篇

ThreadPoolExecutor类核心方法execute如下:

public void execute(Runnable command{
    if (command == null)
        throw new NullPointerException();

    int c = ctl.get();
    if (workerCountOf(c) < corePoolSize) {
        if (addWorker(command, true))
            return;
        c = ctl.get();
    }
    if (isRunning(c) && workQueue.offer(command)) {
        int recheck = ctl.get();
        if (! isRunning(recheck) && remove(command))
            reject(command);
        else if (workerCountOf(recheck) == 0)
            addWorker(nullfalse);
    }
    else if (!addWorker(command, false))
        reject(command);
}

ThreadPoolExecutor类的任务调度逻辑如下图:

线程池探索之基础篇
avatar

核心代码为:

三、线程池的工厂类:

    
ThreadPoolExecutor类来自JDK提供的一套Executor框架,框架结构图如下:

线程池探索之基础篇
avatar

    
Executor框架提供了各种类型的线程池,其内部都是通过ThreadPoolExecutor来实现的,主要有以下工厂方法:

public static ExecutorService newFixedThreadPool(int nThreads)
public static ExecutorService newSingleThreadExecutor()
public static ExecutorService newCachedThreadPool()
public static ScheduledExecutorService newSingleThreadScheduledExecutor()
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize)

下面来一一描述上述工厂方法:

  • newFixedThreadPool()方法返回一个固定线程数量的线程池。源码如下:

public static ExecutorService newFixedThreadPool(int nThreads) {
    return new ThreadPoolExecutor(nThreads, nThreads,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>());
}
  • newSingleThreadExecutor()方法返回一个只有一个线程的线程池。源码如下:

public static ExecutorService newSingleThreadExecutor() {
    return new FinalizableDelegatedExecutorService
        (new ThreadPoolExecutor(11,
                                0L, TimeUnit.MILLISECONDS,
                                new LinkedBlockingQueue<Runnable>()));
}
  • newCachedThreadPool()方法返回一个核心线程数为0,最大线程数为Integer.MAX_VALUE的线程池。源码如下:

public static ExecutorService newCachedThreadPool() {
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                  60L, TimeUnit.SECONDS,
                                  new SynchronousQueue<Runnable>());
}
  • newSingleThreadScheduledExecutor方法返回一个ScheduledExecutorService,线程池大小为1。ScheduledExecutorService是在ExecutorService的基础上增加了定时执行任务的功能。源码如下:

public static ScheduledExecutorService newSingleThreadScheduledExecutor() {
    return new DelegatedScheduledExecutorService
        (new ScheduledThreadPoolExecutor(1));
}

public ScheduledThreadPoolExecutor(int corePoolSize) {
    super(corePoolSize, Integer.MAX_VALUE,
          DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS,
          new DelayedWorkQueue());
}
  • newScheduledThreadPool()方法也返回一个ScheduledExecutorService,但可指定线程池的线程数量。源码如下:

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

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

阿里开发手册中规定:线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式,这样的处理方式让写的同学更加明确线程池的运行规则,避免资源耗尽的风险。

Executors返回的线程池对象的弊端如下:

1) FixedThreadPool和SingleThreadPool:

允许的请求队列长度为Integer.MAX_VALUE,可能会堆积大量的请求,从而导致OOM。

2) CachedThreadPool和ScheduledThreadPool:

允许创建的线程数量为Integer.MAX_VALUE,可能会创建大量的线程,从而导致OOM。


本篇文章来源于微信公众号: 冥oo迹

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/10824.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!