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 {@Overridepublic 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 {@Overridepublic 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利用率