java常用的六种线程池

  • FixedThreadPool(固定线程池)
  • CachedThreadPool(缓存线程池)
  • ScheduledThreadPool(预定/已安排的线程池)
  • SingleThreadExecutor
  • SingleThreadScheduledExecutor
  • ForkJoinPool

一 、FixedThreadPool

顾名思义就是固定容量的线程池,它的容量是固定的,通过构造方法传递线程池运行线程的数量。

//第一个参数:传递一个int线程的大小,核心线程数
//2.最大线程数,=核心线程数。3.最大的存活时间4.时间单位
//5.阻塞队列
public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
                  
public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), defaultHandler);
    }

创建一个线程池这个线程会创建核心线程数,因为最大线程数等于核心线程数(一般的当阻塞队列满员时,就会创建线程以达到最大线程数),所以当不会额外创建线程,所以keepAliveTime也为0。
然后,看这个阻塞队列,用的是LinkedBlockingQueue,链表的形式,它是没有容量限制的,所以所有进入线程池的线程都会进入里面等待,等待核心线程有空位。在this()里面有两个多余的参数是线程工厂的初始化和拒绝策略。
适用:执行长期任务。

二 、CachedThreadPool

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

我们可以看到核心数为0,最大为MAX_VALUE = 0x7fffffff,也就是2的31次方-1,基本上相当于无限大60L, TimeUnit.SECONDS表示线程不工作的时候60s释放线程,而后面这个阻塞队列属于手把手交易的一种方式,有线程直接交给消费,里面没有存储线程的内存。
适用:执行很多短期异步的小程序或者负载较轻的服务器(来任务用任务,没有任务删除线程)

三 、ScheduledThreadPool

支持定时和周期性的执行任务

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

使用的阻塞队列为DelayedWorkQueue()。支持周期性的执行任务

public ScheduledFuture<?> schedule(Runnable command,
                                       long delay,
                                       TimeUnit unit)
 public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
                                                  long initialDelay,
                                                  long period,
                                                  TimeUnit unit)  
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,
                                                     long initialDelay,
                                                     long delay,
                                                     TimeUnit unit)
                                                                                     
  1. 每隔一段时间执行一次任务
  2. period 两次任务的间隔数
  3. delay一次任务执行结束,到下一次任务的延迟
    适用于:周期性任务

四、SingleThreadExecutor

new ThreadPoolExecutor(1, 1,
                 0L, TimeUnit.MILLISECONDS,
                 new LinkedBlockingQueue<Runnable>())

核心和最大线程数为1,并且用的链式阻塞队列(无限制个数),能保证任务执行的顺序等于提交的顺序。
适用:于一个任务一个任务执行的场景

五、SingleThreadScheduledExecutor

new ScheduledThreadPoolExecutor(1)
 super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
              new DelayedWorkQueue());

核心1,最大Integer.MAX_VALUE,使用的是延迟任务队列和第三种ScheduledThreadPool有点相似,是一种特列ScheduledThreadPool是自定义核心线程数,但单例时间线程池是必须为1的。
适用:周期,一个一个运行三和四的结合

五、ForkJoinPool(拆分汇总)

在这里插入图片描述
斐波那契额数列的一个应用

import edu.princeton.cs.algs4.StdOut;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;

public class FeiBoNaQie extends RecursiveTask<Integer> {

    int n;
    public FeiBoNaQie(int n) {
        this.n = n;
    }
    @Override
    protected Integer compute() {
        if(n<=1)return n;
        FeiBoNaQie f1=new FeiBoNaQie(n-1);
        f1.fork();
        FeiBoNaQie f2=new FeiBoNaQie(n-2);
        f2.fork();
        return f1.join()+f2.join();
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
          ForkJoinPool pool=new ForkJoinPool();
          for(int i=0;i<10;i++){
              ForkJoinTask<Integer> task=pool.submit(new FeiBoNaQie(i));
              System.out.println(task.get());
        }
    }
}
0
1
1
2
3
5
8
13
21
34

这就就和递归很相似,不过就是分线程,每个线程里面有一个双端队列,队列是先进先出FIFO,存储分裂出的子任务,,适合数的遍历,最优路径搜索等场景,听说里面会相互协作 work-stealing,队列任务之间能相互帮忙,避免闲着没事做,从而提高效率。没看源码。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值