线程池
以前写多线程的弊端:用到线程时就创建,用完之后线程消失,浪费资源
线程池的主要核心原理:
- 创建一个池子,池子中是空的
- 提交任务时,池子会创建新的线程对象,任务执行完毕,线程归还给池子,下次再提交任务时,不需要创建新的线程,直接复用已有的线程就好了
- 如果提交任务时,池子中没有空闲的线程,也无法创建新的线程,任务就会排队等待
代码实现:
代码实现如下:
public class MyRunnable implements Runnable {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName() + "----"+i);
}
}
}
public class MyThreadPoolDemo {
public static void main(String[] args) throws InterruptedException {
//1.获取线程池对象
//ExecutorService pool1 = Executors.newCachedThreadPool();
ExecutorService pool1 = Executors.newFixedThreadPool(3);
//2.提交任务
pool1.submit(new MyRunnable());
pool1.submit(new MyRunnable());
pool1.submit(new MyRunnable());
pool1.submit(new MyRunnable());
pool1.submit(new MyRunnable());
//3.销毁线程池,线程池一般不销毁
//pool1.shutdown();
}
}
自定义线程池
核心元素如下图:
任务拒绝策略
默认为AbortPolicy
代码实现如下:
public class MyThreadPoolDemo {
public static void main(String[] args) {
ThreadPoolExecutor pool = new ThreadPoolExecutor(
3,//核心线程数量,能小于0
6,//最大线程数量,最大线程数量>=核心线程数量
60,//空闲线程最大存活时间
TimeUnit.SECONDS,//空闲线程存活时间单位
new ArrayBlockingQueue<>(3),//任务队列,3表示队伍长度
Executors.defaultThreadFactory(),//创建线程工厂
new ThreadPoolExecutor.AbortPolicy()//任务拒绝策略,ThreadPoolExecutor类里的静态内部类
);
pool.submit(new MyRunnable());
}
}
小结
不断的提交任务,会有以下三个临界点:
- 当核心线程满时,再提交任务就会排队
- 当核心线程满,队伍满时,会创建临时线程
- 当核心线程满,队伍满,临时线程满时,会触发任务拒绝策略
- 先提交的任务不一定先执行