一马平川
不积跬步无以至千里,后继才能薄发

Java线程池的四种预设创建方式和原生创建方式

2020年07月18日
0
未分类

Java线程池

什么是线程池?

线程池负责维护一个或多个线程的运行,让我们在实际的项目编码中不用自己编写维护线程的逻辑,简化编程,提高代码的鲁棒性,易读性。

线程池的创建方法

通过java.util.concurrent.ThreadPoolExecutor创建

构造方法

ThreadPoolExecutor构造方法

1
2
3
4
5
6
7
8
9
10

public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
//省略实际代码
}

构造参数

  • corePoolSize:核心线程大小
  • maxiumumPoolSize:最大线程大小
  • keepAliveTime:非核心线程的闲置线程存活时间
  • unit:闲置时间单位
  • workQueue:工作队列
  • threadFactory:线程工厂
  • handler:线程溢出处理
线程池规则
  1. 如果线程数量<=核心线程数量,那么直接启动一个核心线程来执行任务,不会放入队列中。
    如果线程数量>核心线程数,但<=最大线程数,并且任务队列是LinkedBlockingDeque的时候,超过核心线程数量的任务会放在任务队列中排队。
  2. 如果线程数量>核心线程数,但<=最大线程数,并且任务队列是SynchronousQueue的时候,线程池会创建新线程执行任务,这些任务也不会被放在任务队列中。这些线程属于非核心线程,在任务完成后,闲置时间达到了超时时间就会被清除。
  3. 如果线程数量>核心线程数,并且>最大线程数,当任务队列是LinkedBlockingDeque,会将超过核心线程的任务放在任务队列中排队。也就是当任务队列是LinkedBlockingDeque并且没有大小限制时,线程池的最大线程数设置是无效的,他的线程数最多不会超过核心线程数。
  4. 如果线程数量>核心线程数,并且>最大线程数,当任务队列是SynchronousQueue的时候,会因为线程池拒绝添加任务而抛出异常。

通过java.util.concurrent.Executors的四种预设创建方式

实际上通过Executors的预设创建线程池,也是通过ThreadPoolExecutor类创建

  • newCachedThreadPool:创建核心线程数为0,最大线程为Integer.MAX的线程池,进入线程池的线程会立刻执行,闲置超过60s清除
1
2
3
4
5
6
//Executors.newCachedThreadPool()方法
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
  • newFixedThreadPool :创建指定核心线程数,最大线程数与核心线程数相同,没有非核心线程所以闲置时间为0,当前核心线程运行中的线程<最大线程时,线程立刻执行,否则压队列,队列中线程会在核心线程中的线程执行完后执行
1
2
3
4
5
6
//Executors.newFixedThreadPool()方法
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
  • newScheduledThreadPool:创建一个定长线程池,支持定时及周期性任务执行
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//Executors.newScheduledThreadPool()方法
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
return new ScheduledThreadPoolExecutor(corePoolSize);
}


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

//ScheduledThreadPoolExecutor.ScheduledThreadPoolExecutor()
public ScheduledThreadPoolExecutor(int corePoolSize,
ThreadFactory threadFactory) {
super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
new DelayedWorkQueue(), threadFactory);
}
  • newSingleThreadExecutor:创建一个同时只有一个线程执行的线程池,超过执行数量的线程会进入队列,和newFixedThreadPool的区别只有同时运行线程数的区别
1
2
3
4
5
6
7
//Executors.newSingleThreadExecutor()方法
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}

如果喜欢这篇文章,可以给作者评个份哦~

原文声明: "转载本站文章请注明作者和出处Nothinglin ,请勿用于任何商业用途"

公众号:苦逼的学生仔