线程池
通过使用线程池中的线程, 大大降低了创建销毁线程所浪费的资源, 当我们需要一个线程时, 从线程池中取出, 用完再放回, 可以提高代码复用性
创建线程池的两种方式
1.使用Executors工具类的方法创建线程:
public ExecutorService newFixedThreadPool(int n): 创建一个指定线程数可重用的线程池。
示例代码:
public class ThreadPoolDemo1 {
public static void main(String[] args) {
// 使用工具类创建线程池
ExecutorService pool = Executors.newFixedThreadPool(5);
for (int i = 0; i < 5; i++) {
// 循环使用线程中的线程执行线程任务
pool.submit(()->System.out.println(Thread.currentThread().getName()+"当前线程池中的线程执行了!"));
}
//线程池中需要手动停止 不然会一直运行等待接收线程任务
pool.shutdown();
}
}
2.自定义线程池通过创建ThreadPoolExecutor对象(7个参数),ThreadPoolExecutor提供了四个构造方法:
我们以一个构造方法(参数最多的那个),对其参数进行解释:
public ThreadPoolExecutor(int corePoolSize, //1
int maximumPoolSize, //2
long keepAliveTime, //3
TimeUnit unit, //4
BlockingQueue<Runnable> workQueue, //5
ThreadFactory threadFactory, //6
RejectedExecutionHandler handler ) { //7
if (corePoolSize < 0 ||
maximumPoolSize <= 0 ||
maximumPoolSize < corePoolSize ||
keepAliveTime < 0)
throw new IllegalArgumentException();
if (workQueue == null || threadFactory == null || handler == null)
throw new NullPointerException();
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}
序号 | 名称 | 类型 | 含义 |
---|---|---|---|
1 | corePoolSize | int | 核心线程池大小 |
2 | maximumPoolSize | int | 最大线程池大小 (核心线程数+临时线程数= 总和) |
3 | keepAliveTime | long | 线程最大空闲时间 |
4 | unit | TimeUnit | 时间单位 |
5 | workQueue | BlockingQueue | 线程等待队列 |
6 | threadFactory | ThreadFactory | 线程创建工厂 |
7 | handler | RejectedExecutionHandler | 拒绝策略 |
public class ThreadPoolDemo2 {
public static void main(String[] args) throws InterruptedException {
ThreadPoolExecutor pool = new ThreadPoolExecutor(3,10,20, TimeUnit.SECONDS,
new ArrayBlockingQueue<>(10), Executors.defaultThreadFactory(),new ThreadPoolExecutor.DiscardPolicy());
for (int i = 0; i < 10; i++) {
pool.submit(()-> System.out.println(Thread.currentThread().getName()+"线程执行了"));
Thread.sleep(300);
}
pool.shutdown();
}
}
通过自定义线程池,我们可以更好的让线程池为我们所用,更加适应我的实际场景。