Executors详解

1 介绍

Executors,Java并发包中提供了类似于工厂方法的类,用于创建不同的ExecutorService,当然还包括拒绝策略、ThreadFactory等

2 方法

2.1 FixedThreadPool

// 创建ExecutorService,指定核心线程数
public static ExecutorService newFixedThreadPool(int nThreads) {
    return new ThreadPoolExecutor(nThreads, nThreads,
                            0L, TimeUnit.MILLISECONDS,
                            new LinkedBlockingQueue<Runnable>());
}

/ 创建ExecutorService,指定核心线程数和ThreadFactory
public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
    return new ThreadPoolExecutor(nThreads, nThreads,
                            0L, TimeUnit.MILLISECONDS,
                            new LinkedBlockingQueue<Runnable>(),
                            threadFactory);
}
  • 核心线程数和最大线程数是相等的,因此该线程池中的工作线程数将始终是固定的。
  • 任务队列为LinkedBlockingQueue(无边界),所以理论上提交至线程池的任务始终都会被执行,只有显式地执行线程池的关闭方法才能关闭线程池。

2.2 SingleThreadPool

/ 创建只有一个工作线程的线程池
public static ExecutorService newSingleThreadExecutor() {
    return new FinalizableDelegatedExecutorService
        (new ThreadPoolExecutor(1, 1,
                            0L, TimeUnit.MILLISECONDS,
                            new LinkedBlockingQueue<Runnable>()));
}


// 创建只有一个工作线程的线程池,并指定ThreadFactory
public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
    return new FinalizableDelegatedExecutorService
        (new ThreadPoolExecutor(1, 1,
                            0L, TimeUnit.MILLISECONDS,
                            new LinkedBlockingQueue<Runnable>(),
                                                        threadFactory));
}

static class FinalizableDelegatedExecutorService extends DelegatedExecutorService {
    FinalizableDelegatedExecutorService(ExecutorService executor) {
        super(executor);
	}
    // 重写finalize方法
    protected void finalize() {
        // 当gc发生的时候,线程池会被执行shutdown
        super.shutdown();
    }
}
  • SingleThreadPool是只有一个核心线程的线程池,
  • 但是Finalizable代理了该线程池,因此当线程池引用可被垃圾回收器回收时,线程池的shutdown方法会被执行,当然我们还是建议显式地调用线程池的关闭方法。

2.3 CachedThreadPool

// 创建Cached线程池
public static ExecutorService newCachedThreadPool() {
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                             60L, TimeUnit.SECONDS,
                             new SynchronousQueue<Runnable>());
}
// 创建Cached线程池并指定ThreadFactory
public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                            60L, TimeUnit.SECONDS,
                            new SynchronousQueue<Runnable>(),
                            threadFactory);
}

CachedThreadPool根据需要创建新线程,但会重用以前构造的可用线程。该线程池通常会用于提高执行量大的、耗时较短的、异步任务程序的运行性能,在该线程池中,如果有可用的线程将被直接重用。如果没有可用的线程,则会创建一个新线程并将其添加到池中。未被使用且空闲时间超过60秒的线程将被终止并从线程池中移除,因此长时间空闲的线程不会消耗任何资源。

2.4 ScheduledThreadPool

// 构造指定核心线程数的ScheduledThreadPoolExecutor
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
    return new ScheduledThreadPoolExecutor(corePoolSize);
}

// 指定核心线程数和ThreadFactory
public static ScheduledExecutorService newScheduledThreadPool(
        int corePoolSize, ThreadFactory threadFactory) {
    return
    new ScheduledThreadPoolExecutor(corePoolSize, threadFactory);
}

2.5 WorkStealingPool

// 并发度等于CPU核数
public static ExecutorService newWorkStealingPool() {
    return new ForkJoinPool
        (Runtime.getRuntime().availableProcessors(),
         ForkJoinPool.defaultForkJoinWorkerThreadFactory,
         null, true);
}
// 允许指定并发度
public static ExecutorService newWorkStealingPool(int parallelism) {
    return new ForkJoinPool
        (parallelism,
         ForkJoinPool.defaultForkJoinWorkerThreadFactory,
         null, true);
}

WorkStealingPool是在JDK1.8版本中引入的线程池,它的返回结果是ForkJoinPool,而不是ScheduledThreadPoolService或ThreadPoolExecutor。
与其他线程池不同的是,WorkStealingPool中的工作线程会处理任务队列中与之对应的任务分片(Divide and conquer:分而治之),如果某个线程处理的任务执行比较耗时,那么它所负责的任务将会被其他线程“窃取”执行,进而提高并发处理的效率。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值