一、线程池的参数介绍
Java标准库中 线程池 构造方法的参数和含义。
下面的构造方法描述均摘自Java官方文档:
ThreadPoolExecutor是最原始的线程池创建方法,后面的Executors创建线程池的方法是对ThreadPoolExecutor进行进一步封装而得到的。
1、int corePoolSize(核心线程数)
表示线程池中含有的最小数量的线程数。ThreadPoolExecutor中的线程个数并非固定不变的,是根据当前任务的变化自动创建。
核心线程数就是哪怕你线程池没一点任务,你也要创建这么多线程在那。
2、int maximumPoolSize(最大线程数)
表示线程池中含有的最大数量的线程数。
哪怕你线程池再忙,你也只能创建出这么多线程。
3、long keepAliveTime
在核心线程之上创建的新的线程所能允许空闲的最大时间。
4、TimeUnit unit
是(3)中的所能允许空闲时间的 时间单位。
是秒(s)、毫秒(ms)这种表示时间的单位。
5、BlockingQueue<Runnable> workQueue
线程池内有很多任务,这些任务用一个阻塞队列来进行管理。
线程池内可以内置阻塞队列,也可以按照自己的需求自己设置一个阻塞队列。
6、ThreadFactory threadFactory(工厂模式)
通过这个工厂类来创建线程。
7、RejectedExecutionHandler handler(拒绝方式/拒绝策略)
当线程池中的阻塞队列满了的时候,再往线程池中添加任务,我们不想使任务等待,此时线程池如何应对添加任务的方法。
线程池标准库中为我们提供了以下拒绝策略:
1)这个是直接抛异常,线程池直接不干活了。
2) 谁是添加这个新任务的线程,谁就去执行这个任务。
3)接到新任务的线程丢弃最早的任务,去执行新的任务.
4)接到新的任务的线程直接把新的任务给丢弃了。
二、线程池的工作流程
1)任务到来后,线程池先判断线程数是否达到了核心线程数。如果未达到核心线程数,则由核心线程处理任务;否则,就执行下一步;
2)判断线程池的阻塞队列满了没有。如果没满,则将任务添加到阻塞队列中;否则,执行下一步;
3)判断线程数是否达到了最大线程数。如果未达到,则创建非核心线程处理任务;否则,就执行拒绝策略,默认会抛出RejectedExecutionException异常。
三、使用Executors 创建常见的线程池
Java标准库中为我们提供的现成的线程池:
1)创建出一个固定线程数量的线程池。
2)创建出一个线程数量动态变化的线程池。
3)创建出一个包含单个线程的线程池。
这个方法要比原生创建单个线程的方法更简单一些,还更容易替换成其他模式的线程池。
4) 类似于创建一个和定时器差不多的线程池。
添加一些任务,任务都在后续的某些时刻执行。
但与定时器不同的是,执行任务时不止只有一个扫描线程来执行任务,而是由多个线程共同执行所有任务。
实例演示:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Demo2 {
public static void main(String[] args) {
ExecutorService service= Executors.newFixedThreadPool(6);
for(int i=0;i<100;i++){
service.submit(new Runnable() {
@Override
public void run() {
System.out.println("aaa");
}
});
}
}
}
运行结果:
出现100个aaa