线程池的作用
1.降低资源消耗:通过重复利用已创建的线程降低线程创建和销毁造成的消耗
2.提高响应速度:当有任务时,任务可以不需要等到线程创建就能立即执行
2.提高线程的可管理性:线程池可以进行统一的分配,调优和监控
为什么使用线程池
使用Runnable,一个线程只能执行一个任务,执行多个任务需要创建多个线程
线程池分配线程执行,其中的线程可复用
单一线程池展示
public static void main(String[] args) {
Runnable task1 = new Task();
Runnable task2 = new Task();
Runnable task3 = new Task();
//创建只有一个线程的线程池
ExecutorService theadPool = Executors.newSingleThreadExecutor();
//提交任务
theadPool.execute(task1);
theadPool.execute(task2);
theadPool.execute(task3);
//关闭线程池
theadPool.shutdown();
}
上述线程池通过Executors等方式创建有资源耗尽的风险,尽量使用ThreadPoolExecutor创建
原生方式创建线程池
构造方法
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
参数信息
corePoolSize:核心线程数
maximumPoolSize:最大线程数
keepAliveTime:空闲线程存活时间
unit:时间单位
new ThreadPoolExecutor(10, 25, 10, TimeUnit.SECONDS)
//空闲线程的存活时间为10s,超过10s没工作便销毁
//线程池不关闭,核心线程不会被销毁,线程池中最多存在25个线程
workQueue:存放任务的容器,提交给线程池的任务存在这
-LinkedBlockingQueue链式阻塞队列
-ArrayBlockingQueue数组阻塞队列
threadFactory:可以指定线程如何生产,是一个接口,实现可以自定义线程的相关设置,如:线程名称,线程是否为后台线程
handler:任务拒绝策略
会被拒绝的情况:以下4种情况需同时满足
1.线程池中的线程已满
2.无法继续扩容
3.没有空闲线程
4.任务队列已满
任务拒绝策略 描述 DiscardPolicy 直接丢弃任务 CallerRunsPolicy 使用调用者线程直接执行被拒绝的任务 AbortPolicy 默认的拒绝策略,抛出RejectedExecutionException异常 DiscardOldestPolicy 丢弃处于任务队列头部的任务,添加被拒绝的任务
具体代码
CustomThteadFactory类
threadFactory参数的信息
自定义线程工厂类
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;
//自定义线程工厂
public class CustomThteadFactory implements ThreadFactory {
/**
* 计数器
* 线程安全
*/
private final AtomicInteger i = new AtomicInteger(1);
@Override
public Thread newThread(Runnable r) {
//创建线程,并执行任务
Thread thread = new Thread(r);
//设置线程名称
thread.setName("线程" + i.getAndIncrement() + "号");
return thread;
}
}
Main类
import java.util.concurrent.*;
public class Main {
public static void main(String[] args) {
//创建任务
Task task1 = new Task();
Task task2 = new Task();
Task task3 = new Task();
//创建线程池
ThreadPoolExecutor threadPool = new ThreadPoolExecutor(10, 25, 10L,
TimeUnit.SECONDS,
new LinkedBlockingQueue<>(),
new CustomThteadFactory(),
new ThreadPoolExecutor.AbortPolicy());
//提交任务
threadPool.execute(task1);
threadPool.execute(task2);
threadPool.execute(task3);
//关闭线程池
threadPool.shutdown();
}
}
class Task implements Runnable {
@Override
public void run() {
//获取当前线程
Thread thread = Thread.currentThread();
System.out.println(thread.getName());
}
}