目录
一、线程池
线程池,按照配置参数(核心线程数、最大线程数等)创建并管理若干线程对象。程序中如果需要使用线程,将一个执行任务传给线程池,线程池就会使用一个空闲状态的线程来执行这个任务。执行结束以后,该线程并不会死亡,而是再次返回线程池中成为空闲状态,等待执行下一个任务。使用线程池可以很好地提高性能。
二、线程池的执行流程
1. 向线程池提交一个新的线程任务,线程池会分配一个空闲线程来执行这个任务。
2. 当线程池中没有空闲线程时,线程池会判断当前存活的线程数与线程池中的核心线程数(corePoolSize):
1) 小于核心线程数时,线程池会创建一个新的核心线程来执行这个任务;
2) 大于核心线程数时,线程池会检查工作队列是否存满:
1)) 工作队列未满时,线程池将该任务放入工作队列中等待,当线程池中出现空闲队列时, 将该任务从工作队列中调出,交给该空闲线程执行;
2)) 工作队列已满时,线程池会判断线程数是否达到线程池中的最大线程数:
1))) 未超出最大线程数时,线程池会创建一个新的非核心心线程来执行该认为有;
2))) 超出最大线程数时,线程池会执行拒绝策略来处理该任务。
综上所述,线程池的执行顺序为:核心线程、工作队列、非核心线程、拒绝策略。
三、线程池的状态
1. RUNNING:运行状态。线程池被一旦被创建,就处于RUNNING状态,并且线程池中的任务数为0。该状态的线程池会接收新任务,并处理工作队列中的任务。
2. SHUTDOWN:关闭状态。线程池调用shutdown()方法,进入关闭状态,此时线程池不会接收新任务,但会处理工作队列中的任务。
3. STOP:停止状态。线程池调用shutdownnow()方法,进入停止状态,此时线程池不会接受新任务,也不会处理工作队列中的任务,而且会中断工作队列中的任务。
4. TIDYING:整理状态。线程池的工作队列为空,并且需要执行的任务也为空时,进入整理状态,该状态表明所有的任务已经运行终止,记录的任务数量为0。
5. TERMINATED:终止状态。terminated()执行完毕,进入终止状态,该状态表示线程池彻底关闭。
四、线程池的分类
1. FixedThreadPool:线程数固定的线程池,使用Executors.newFixedThreadPool()创建。
public class threadPool01 {
public static void main(String[] args) {
// 创建一个固定大小的线程池
ExecutorService executorService = Executors.newFixedThreadPool(4);
for (int i = 0; i < 6; i++) {
executorService.execute(new Task("线程"+i));
}
// 关闭线程池:
executorService.shutdown();
}
}
class Task01 implements Runnable {
private String taskName;
public Task(String taskName) {
this.taskName = taskName;
}
public void run() {
System.out.println("启动线程 ===> " + this.taskName);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
System.out.println("结束线程 <= " + this.taskName);
}
}
2. CachedThreadPool:线程数根据任务动态调整的线程池,使用Executors.newCachedThreadPool()创建。
将thread01类中的
//创建一个固定大小的线程池
ExecutorService executorService = Executors.newFixedThreadPool(4);
改为
ExecutorService executorService=Executors.newCachedThreadPool();
3. ScheduledThreadPool:能实现定时、周期性任务的线程池,使用Executors.newScheduledThreadPool()创建。
public class threadPool02 {
public static void main(String[] args) {
ScheduledExecutorService executorService=Executors.newScheduledThreadPool(1);
System.out.println("当前时间:"+LocalDateTime.now());
//延迟3秒后执行任务,执行一次
//executorService.schedule(new Task("任务A"), 3, TimeUnit.SECONDS);
//延迟2秒后执行任务,以后每隔3秒执行一次
//executorService.scheduleAtFixedRate(new Task("任务A"), 2, 3, TimeUnit.SECONDS);
//延迟1秒后执行任务,以后每隔4(3+1)秒执行一次
executorService.scheduleWithFixedDelay(new Task("任务A"), 1, 3, TimeUnit.SECONDS);
}
}
4. SingleThreadExecutor:仅提供一个单线程的线程池,使用Executors.newSingleThreadExecutor()创建。
五、创建线程池
自定义线程工厂:
public class MyThreadFactory implements ThreadFactory {
//使用AtomicInteger定义n,防止出现多线程同时访问
private final AtomicInteger n = new AtomicInteger(0);
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setName("订单线程" + n、.incrementAndGet());
return t;
}
}
Task02类:
class Task02 implements Runnable{
public void run() {
System.out.println("启动线程 ===> "+Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("关闭线程 <= "+Thread.currentThread().getName());
}
}
创建线程池:
public class threadPool03 {
public static void main(String[] args) {
ExecutorService executorService=new ThreadPoolExecutor(10, 11, 1, TimeUnit.SECONDS, new LinkedBlockingDeque<Runnable>(), new MyThreadFactory());
for(int i=1;i<=6;i++) {
executorService.execute(new Task());
}
executorService.shutdown();
}
}
线程池的配置参数:
1. corePoolSize:线程池核心线程数。线程池维护的最小线程数量,核心线程创建后不会被回收。
2. maximumPoolSize:线程池最大线程数。线程池允许创建的最大线程数量(包含核心线程池数量)。
3. keepAliveTime:非核心线程线程存活时间。当一个非核心线程的空闲时间大于keepAliveTime,就会被回收。
4. TimeUnit:时间单位。参数keepAliveTime的时间单位。
5. BlockingQueue:阻塞工作队列。用来存储等待执行的任务。
6. ThreadFactory:线程工厂 :。用于创建线程,以及自定义线程名称,需要实现ThreadFactory接口。