1. 线程池
主要核心原理
不推荐Executors创建没有上线的线程池,建议使用自定义的线程池;
Java工具类创建线程池;
public class demo16 {
public static void main(String[] args) {
/**
* public static ExecutorService newCachedThreadPoo1() 创建个没有上限的线程池
* public static ExecutorService newFixedThreadPool (int nThreads) 创有上限的线程池
*/
//1. 获取线程池对象
//ExecutorService pool1 = Executors.newCachedThreadPool();
ExecutorService pool1 = Executors.newFixedThreadPool(3);
//2. 提交任务
pool1.submit(new MyRunnable16());
pool1.submit(new MyRunnable16());
pool1.submit(new MyRunnable16());
pool1.submit(new MyRunnable16());
//3. 销毁线程池
//pool1.shutdown();
}
}
class MyRunnable16 implements Runnable {
@Override
public void run() {
for (int i = 1; i <= 100; i++) {
System.out.println(Thread.currentThread().getName() + "---" + i);
}
}
}
2. 自定义线程池
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
- 当只有3个任务时,直接上处理机运行;
- 当有6个任务时,任务1-3上处理机运行,任务4-6进入阻塞队列等待;
- 当有9个任务时,任务1-3上处理机运行,任务4-6进入阻塞队列等待,任务7-9由3个临时线程处理运行;
- 当有10个任务时,任务1-3上处理机运行,任务4-6进入阻塞队列等待,任务7-9由3个临时线程处理运行,任务10触发任务拒接策略(此时核心线程和临时线程均在工作,且阻塞队列已满);
任务拒接策略
示例代码:
public class poolDemo1 {
public static void main(String[] args) {
/**
* ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor
* (核心线程数量,最大线程数量,空闲线程最大存活时间,任务队列,创建线程工厂,任务的拒绝策略);
* 参数一:核心线程数且 不能小于0
* 参数二:最大线程数 不能小于等于0,最大数量 >= 核心线程数量
* 参数三:空闲线程最大存活时间 不能小于0
* 参数四:时间单位 用TimeUnit指定
* 参数五:任务队列 不能为nu11
* 参数六:创建线程工厂 不能为nu11
* 参数七:任务的拒绝策略 不能为nu11
*/
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
3,
6,
60,
TimeUnit.SECONDS,
new ArrayBlockingQueue<>(3),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy()
);
// 开9个任务,观察输出结果比较明显
threadPoolExecutor.submit(new MypoolRunnable());
threadPoolExecutor.submit(new MypoolRunnable());
threadPoolExecutor.submit(new MypoolRunnable());
threadPoolExecutor.submit(new MypoolRunnable());
threadPoolExecutor.submit(new MypoolRunnable());
threadPoolExecutor.submit(new MypoolRunnable());
threadPoolExecutor.submit(new MypoolRunnable());
threadPoolExecutor.submit(new MypoolRunnable());
threadPoolExecutor.submit(new MypoolRunnable());
}
}
class MypoolRunnable implements Runnable {
@Override
public void run() {
for (int i = 1; i <= 100; i++) {
System.out.println(Thread.currentThread().getName() + "---" + i);
}
}
}
自定义的线程池应该多大?
首先给出最大并行数,该cpu是10核16线程,最大并行数应该是16;
或者可以在idea中输出下面代码,也可以得到最大最大并行数;
System.out.println(Runtime.getRuntime().availableProcessors());
根据程序的类型,考虑cpu和I/O利用率