Java 多线程七:线程池
发布时间:2023-04-17 11:39:36 所属栏目:教程 来源:
导读:线程池内部是通过队列结合线程实现的,当我们利用线程池执行任务时:
如果此时线程池中的线程数量小于corePoolSize,即使线程池中的线程都处于空闲状态,也要创建新的线程来处理被添加的任务。
如果此时线程池
如果此时线程池中的线程数量小于corePoolSize,即使线程池中的线程都处于空闲状态,也要创建新的线程来处理被添加的任务。
如果此时线程池
|
线程池内部是通过队列结合线程实现的,当我们利用线程池执行任务时: 如果此时线程池中的线程数量小于corePoolSize,即使线程池中的线程都处于空闲状态,也要创建新的线程来处理被添加的任务。 如果此时线程池中的线程数量等于corePoolSize,但是缓冲队列workQueue未满,那么任务被放入缓冲队列。 如果此时线程池中的线程数量大于等于corePoolSize,缓冲队列workQueue已满,并且线程池中的线程数量小于maximumPoolSize,建新的线程来处理被添加的任务。 如果此时线裎池中的线数量大于corePoolSize,缓存冲队列workQueue已满, 并且线程池中的数量等于maximumPoolSize,那么过handler所指定的策略来处理此任务。 当线程池中的线程数量大于corePoolSize时,如果某线程空闲时间超过keepAliveTime, 线将被终止。这样,线程池可以动态的调整池中的线程数。 相关配置 corePoolSize:核心线程数 maximumPoolSize:最大线程数 【包括核心线程数】 keepAliveTime:生存时间【线程长时间不干活了,归还给操作系统,核心线程不用归还,可以指定是否参与归还过程】 生存时间单位 任务队列:等待队列,如果不指定,最大值是Integer.MAX_VALUE【各种各样的BlockingQueue】 线程工厂【默认设置优先级是普通优先级,非守护线程】,最好自定义线程名称,方便回溯 拒绝策略,包括以下四种: ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。 ThreadPoolExecutor.discardPolicy:丢弃任务,但是不抛出异常。 ThreadPoolExecutor.discardOldestPolicy:丢弃队列最前面的任务,然后重新提交被拒绝的任务 ThreadPoolExecutor.CallerRunsPolicy:由调用线程(提交任务的线程)处理该任务 执行流程:先占满核心线程-> 再占满任务队列-> 再占满(最大线程数-核心线程数)-> 最后执行拒绝策略 一般自定义拒绝策略:将相关信息保存到redis,kafka,日志,MysqL记录 实现RejectedExecutionHandler并重写rejectedExecution方法 自定义拒绝策略代码示例: package git.snippets.juc; import java.util.concurrent.*; /** * 自定义拒绝策略 */ public class MyRejectedHandler { public static void main(String[] args) { ExecutorService service = new ThreadPoolExecutor(4, 4, 0, TimeUnit.SECONDS, new ArrayBlockingQueue<>(6), Executors.defaultThreadFactory(), new MyHandler()); } static class MyHandler implements RejectedExecutionHandler { @Override public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { //log("r rejected") //save r kafka MysqL redis //try 3 times if (executor.getQueue().size() < 10000) { //try put again(); } } } } SingleThreadPool 保证线程按顺序执行 为什么要有单线程的线程池?这个主要是用来做任务队列和线程生命周期管理 使用LinkedBlockingQueue作为任务队列,上界为:Integer.MAX_VALUE(2147483647) 约等于无界。 示例代码见: package git.snippets.juc; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import static java.util.concurrent.TimeUnit.SECONDS; public class SingleThreadPoolUsage { public static void main(String[] args) throws InterruptedException { ExecutorService service = Executors.newSingleThreadExecutor(); for (int i = 0; i < 10; i++) { final int j = i; service.submit(() -> System.out.println("current thread " + Thread.currentThread() + " " + j)); } service.shutdown(); service.awaitTermination(60, SECONDS); } } CachedThreadPool corePoolSize:0 maxiumPoolSize:Integer.MAX_VALUE(2147483647) keepAliveTime 60秒 使用SynchronousQueue作为任务队列 必须马上执行 使用示例: package git.snippets.juc; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; public class CachedThreadPoolUsage { public static void main(String[] args) throws InterruptedException { System.out.println("cached thread pool usage..."); ExecutorService service = Executors.newCachedThreadPool(); System.out.println(service); for (int i = 0; i < 2; i++) { service.execute(() -> { try { TimeUnit.MILLISECONDS.sleep(500); } catch (InterruptedException e) { e.printstacktrace(); } System.out.println(Thread.currentThread().getName()); }); } System.out.println(service); TimeUnit.SECONDS.sleep(80); System.out.println(service); } } (编辑:汽车网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
推荐文章
站长推荐
