小编给大家分享一下Java线程池怎么用,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!
线程池是一种用于实现计算机程序并发执行的软件设计模式。线程池维护多个线程,等待由调度程序分配任务以并发执行,该模型提高了性能,并避免了由于为短期任务频繁创建和销毁线程而导致的执行延迟。
说到线程池就一定要从线程的生命周期讲起。
从图中可以了解无论任务执行多久,每个线程都要经历从生到死的状态。而使用线程池就是为了避免线程的重复创建,从而节省了线程的New
至Runnable
, Running
至Terminated
的时间;同时也会复用线程,最小化的节省系统资源,于此同时提高了响应速度。
线程池的创建
使用ThreadPoolExecutor
并配置7个参数完成线程池的创建
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)
corePoolSize:线程池中核心线程的最大值
maximumPoolSize:线程池中最大线程数
keepAliveTime:非核心线程空闲的存活时间大小
unit:keepAliveTime的单位,常用的有秒、分钟、小时等
workQueue:阻塞队列类型
threadFactory:线程工厂,用于配置线程的名称,是否为守护线程等
handler:线程池的拒绝策略
ArrayBlockingQueue
底层基于数组的实现的有界阻塞队列
LinkedBlockingQueue
底层基于单链表的阻塞队列,可配置容量,不配置容量默认为Integer.MAX_VALUE
在《阿里巴巴Java开发手册》中强制要求指定线程的名称
由于工作是使用hutool比较多,里面也包含对ThreadFactory
的封装,可以很方便的指定名称
ThreadFactory threadFactory = ThreadFactoryBuilder.create().setNamePrefix("myThread-").build();
当线程池内工作线程数大于maximumPoolSize时,线程就不再接受任务,执行对应的拒绝策略;目前支持的拒绝策略有四种:
1.AbortPolicy(默认):丢弃任务并抛出RejectedExecutionException
异常
2.CallerRunsPolicy:由调用者处理
3.DiscardOldestPolicy:丢弃队列中最前面的任务,并重新入队列
4.DiscardPolicy:丢弃任务但不抛出异常
// 创建线程工厂 ThreadFactory threadFactory = ThreadFactoryBuilder.create().setNamePrefix("myThread-").build(); // 创建线程池 ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5, 10, 10, TimeUnit.SECONDS, new ArrayBlockingQueue<>(100), threadFactory, new ThreadPoolExecutor.AbortPolicy());
// 组合值;保存了线程池的工作状态和工作线程数 private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
public void execute(Runnable command) { // 任务为空 抛出NPE if (command == null) throw new NullPointerException(); // 获取线程池状态 int c = ctl.get(); // 如果工作线程数小于核心线程数就创建新线程 if (workerCountOf(c) < corePoolSize) { if (addWorker(command, true)) return; c = ctl.get(); } // 如果线程池处于Running状态,就把任务放在队列尾部 if (isRunning(c) && workQueue.offer(command)) { // 重新检查线程池状态 int recheck = ctl.get(); // 如果线程池不是Running状态,就移除刚才添加的任务,并执行拒绝策略 if (! isRunning(recheck) && remove(command)) reject(command); // 是Running状态,就添加线程 else if (workerCountOf(recheck) == 0) addWorker(null, false); } // 添加任务失败,执行拒绝策略 else if (!addWorker(command, false)) reject(command); } // addWorker()完成线程的创建
以上是“Java线程池怎么用”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注亿速云行业资讯频道!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。