多线程之常用线程池实现

为什么要用线程池

线程频繁地创建和销毁的开销巨大,通过线程池来对线程进行统一的管理,以达到线程重用的目的。

如何创建线程池

先贴一段简单的代码,通过Executors可以创建线程池,下面创建的是只有一个线程的线程池。

public class ThreadPoolTest {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newSingleThreadExecutor(); // 创建一个线程的线程池
        executorService.execute(new Runnable() {
            @Override
            public void run() {
                System.out.println("当前执行线程名称:" + Thread.currentThread().getName());
            }
        });
    }
}

---------------------------------------------------------------------------
输出:
当前执行线程名称:pool-1-thread-1

常见四种线程池创建方式

// 创建单个线程线程池
ExecutorService executorService1 = Executors.newSingleThreadExecutor();
// 创建可缓存线程池
ExecutorService executorService2 = Executors.newCachedThreadPool();
// 创建指定核心线程数的线程池
ExecutorService executorService3 = Executors.newFixedThreadPool(5);
// 创建可定时调度并指定核心线程池的线程池
ExecutorService executorService4 = Executors.newScheduledThreadPool(5);

线程池的实现

随便点击创建线程池的方法,你会发现线程池内部是通过ThreadPoolExecutor类,顶层接口是Executor,接口方法execute(Runnable command)。

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

ThreadPoolExecutor详解

ThreadPoolExecutor的继承体系

ThreadPoolExecutor有多个构造器,我们选个最多参数的来详细解析。

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

corePoolSize:线程池核心线程数
maximumPoolSize:线程池最大线程数
keepAliveTime:线程池线程回收超时时长,默认是作用于非核心线程,如果ThreadPoolExecutor的allowCoreThreadTimeOut属性设置为true,也会作用于核心线程
unit:线程回收超时时长的单位(纳秒、微秒、毫秒、秒、分、时、天),可通过枚举类TimeUnit设置
workQueue:缓冲任务队列,当corePoolSize< currentSize < maximumPoolSize时,任务会在队列中排队
threadFactory:为线程池提供创建新线程的线程工厂,使用默认实现DefaultThreadFactory即可。
handler:拒绝策略(线程数达到maximumPoolSize或者线程池关闭时),RejectedExecutionHandler有多个实现类,并且都是ThreadPoolExecutor的静态内部类,默认是AbortPolicy策略。

拒绝策略:

AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。

DiscardPolicy:丢弃任务,但是不抛出异常。

DiscardOldestPolicy:丢弃队列最前面的任务,然后重新提交被拒绝的任务

CallerRunsPolicy:由调用线程(提交任务的线程)处理该任务

线程池执行流程

1,当currentPoolSize < corePoolSize时,直接启动核心线程执行任务。

2,当currentPoolSize >= corePoolSize,而且workQueue未满时,新的任务放到workQueue等待执行。

3,当workQueue已满,而且currentPoolSize < maximumPoolSize时,创建新的非核心线程执行任务。

4,当currentPoolSize >= maximumPoolSize,而且workQueue已满时,新的任务会直接触发拒绝策略,默认抛出RejectExecutionExpection异常。

发布了31 篇原创文章 · 获赞 0 · 访问量 1429

猜你喜欢

转载自blog.csdn.net/weixin_41645232/article/details/105612191