线程池在实际中的使用
实际开发中,最常用主要还是利用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提供了四大常用的函数式接口