线程池在实际中的使用
实际开发中,最常用主要还是利用ThreadPoolExecutor自定义线程池,可以给出一些关键的参数来自定义。
在下面的代码中可以看到,该线程池的最大并行线程数是5,线程等候区(阻塞队列)是3,即该线程池最多接受8个线程任务的同时提交。
一旦超过了8这个任务数,就会抛出java.util.concurrent.RejectedExecutionException拒绝执行异常
任务数8,运行结果:
任务数9,运行结果:
源代码:
import java.util.concurrent.*;
/**
* @author zkw
* @Description 自定义线程池
*/
public class CustomerThreadPool {
public static void main(String[] args) {
ExecutorService threadPool = new ThreadPoolExecutor(
3, //初始线程池并行数
5, //线程池最大并行数
2L, //空闲的线程允许空闲的时间
TimeUnit.SECONDS, //上面参数的单位
new LinkedBlockingQueue<Runnable>(3), //设置等候队列长度,不设置的话会默认使用Integer的最大值
Executors.defaultThreadFactory(), //创建线程的工厂
new ThreadPoolExecutor.AbortPolicy()); //拒绝策略
try {
for (int i = 0; i < 8; i++) {
threadPool.execute(()->{
System.out.println(Thread.currentThread().getName()+"\t正在服务");
});
}
}catch (Exception e){
e.printStackTrace();
}finally {
threadPool.shutdown();
}
}
}
线程池拒绝策略
AbortPolicy(默认):直接抛出RejectedExecutionException异常阻止系统正常运行
CallerRunsPolicy:“调用者运行”一种调节机制,该策略既不会抛弃任务,也不会抛出异常,而是将某些任务回退到调用者,
而降低新任务的流量。(比如是main线程提交的任务,就回退给main线程执行)
DiscardOldestPolicy:抛弃队列中等待最久的任务,然后把当前任务加人队列中尝试再次提交当前任务。
DiscardPolicy该策略默默地丢弃无法处理的任务,不予任何处理也不抛出异常。如果允许任务丢失,这是最好的一种策略。
线程池参数设置细节
如果任务都是cpu密集型,设置线程池大小的时候应该使用的是根据不同电脑的cpu核数来设置的动态的参数
获取cpu核数:
Runtime.getRuntime().availableProcessors()
ExecutorService threadPool = new ThreadPoolExecutor(
3,
Runtime.getRuntime().availableProcessors(), //根据不同cpu设置的动态线程池大小
2L,
TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>(3),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy());
(编程篇)函数式接口
这块知识主要是在看源代码的时候有用,jdk提供了四大常用的函数式接口