线程池 野性酷女 2023-07-18 02:30 1阅读 0赞 > * 多线程为什么快 > > 假设,有任务A和B,有如下两种执行方式 > > 方式一:两个线程,一个线程执行A,另一个线程执行B > > 方式二:一个线程,先执行A,执行完以后继续习性B > > 以上方式其实是方式二更快一些: > > 因为方式一中,CPU在切换线程的时候,有一个上下文切换时间,而这个上下文切换时间是非常耗时的,而一次上下文切换,将近需要耗时0.002ms!而这个时间内,CPU什么都干不了,只是做了保存上下文都动作! > > 一般只用在I/O操作的时候采用多线程,例如磁盘I/O,网络I/O,一般IO操作分为两个阶段:等待I/O资源,操作I/O资源,在等待I/O的时间内,线程是在阻塞的,CPU就空闲了,如果存在其他线程就可以在这段时间内利用CPU去做其他事情,所以IO操作使用多线程更快 > > 然而redis是内存数据库,不涉及IO,所以用单线程更好 > > > * 线程池使用场景 > > 大批量数据需要调用其他系统去校验有效性,比如:异步发送kafka消息,批量用户认证,批量商户商品认证 > > 执行线程方法:executor.submit() > > 活动线程数:executor.getActiveCount(),不太准确,实时变化的 > > 队列实际数:executor.getQueue().size() > > 最大线程峰值:executor.getLargestPoolSize() > > 最小线程数:executor.getCorePoolSize() > > * 线程池避免了线程的重复创建,用完后抛回池中,实现线程的复用,往往不知道几个线程够用,线程够用就不创建,不够用时自己创建 > * java中提供线程池工具类:java.util.concurrent.Executors提供众多的线程池实现方法 > > ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM2MDQyOTM4_size_16_color_FFFFFF_t_70][] > > ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM2MDQyOTM4_size_16_color_FFFFFF_t_70 1][] > * 但是,归更到底都是在 new ThreadPoolExecutor对象,ThreadPoolExecutor是线程池的真正实现 > > java.util.concurrent.Executor 类有子类接口 ExecutorService,抽象类 AbstractExecutorService实现了ExecutorService接口, > > ThreadPoolExecutor 类 继承了抽象类AbstractExecutorService > > ![20200323150328720.png][] > * ThreadPoolUtil采用单例模式: > > ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM2MDQyOTM4_size_16_color_FFFFFF_t_70 2][] > * ThreadPoolUtil的主要参数: > > ![20200323153346738.png][] > > 1.corePoolSize 线程池核心线程大小 > > 线程池中会维护一个最小的线程数量,即使在这些线程空闲状态,他们也不会被销毁,除非设置了allowCoreThreadTimeOut,这里的最小的线程数量即是corePoolSize > > 2.maxmunPoolSize 线程池最大线程数 > > 一个任务被提交到线程池后,首先会缓存到工作队列(后面会介绍)中,如果工作队列满了,则会创建一个新线程,然后从工作队列中的取出一个任务交由新线程来处理,而将刚提交的任务放入工作队列。线程池不会无限制的去创建新线程,它会有一个最大线程数量的限制,这个数量即由maximunPoolSize来指定。 > > 3.keepAliveTime 空闲线程存活时间 > > 一个线程如果处于空闲状态,并且当前的线程数量大于corePoolSize,那么在指定时间后,这个空闲线程会被销毁,这里的指定时间由keepAliveTime来设定 > > 4.unit空闲线程存活时间的单位 > > 5.workQueue 工作队列 > > 新任务被提交后,会先进入到此工作队列中,任务调度时再从队列中取出任务。jdk中提供了四种工作队列: > > ①ArrayBlockingQueue > > 基于数组的有界阻塞队列,按FIFO排序。新任务进来后,会放到该队列的队尾,有界的数组可以防止资源耗尽问题。当线程池中线程数量达到corePoolSize后,再有新任务进来,则会将任务放入该队列的队尾,等待被调度。如果队列已经是满的,则创建一个新线程,如果线程数量已经达到maxPoolSize,则会执行拒绝策略。 > > ②LinkedBlockingQuene > > 基于链表的无界阻塞队列(其实最大容量为Interger.MAX),按照FIFO排序。由于该队列的近似无界性,当线程池中线程数量达到corePoolSize后,再有新任务进来,会一直存入该队列,而不会去创建新线程直到maxPoolSize,因此使用该工作队列时,参数maxPoolSize其实是不起作用的。 > > ③SynchronousQuene > > 一个不缓存任务的阻塞队列,生产者放入一个任务必须等到消费者取出这个任务。也就是说新任务进来时,不会缓存,而是直接被调度执行该任务,如果没有可用线程,则创建新线程,如果线程数量达到maxPoolSize,则执行拒绝策略。 > > ④PriorityBlockingQueue > > 具有优先级的无界阻塞队列,优先级通过参数Comparator实现。 > > 6.threadFactory 线程工厂 > > 创建一个新线程时使用的工厂,可以用来设定线程名、是否为daemon线程等等 > > 7.handler拒绝策略 > > 当工作队列中的任务已到达最大限制,并且线程池中的线程数量也达到了最大限制,这是如果有新任务提交进来,该如何处呢,jdk提供了4中拒绝策略 > > ①CallerRunsPolicy > > 该策略下,在调用者线程中直接执行被拒绝任务的run方法,除非线程池已经shutdown,则直接抛弃任务。 > > ②AbortPolicy(默认) > > 该策略下,直接丢弃任务,并抛出RejectedExecutionException异常。 > > ③DiscardPolicy > > 该策略下,直接丢弃任务,什么都不做。 > > ④DiscardOldestPolicy > > 该策略下,抛弃进入队列最早的那个任务,然后尝试把这次拒绝的任务放入队列 > > [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM2MDQyOTM4_size_16_color_FFFFFF_t_70]: /images/20230528/a44c63a9fa6147e9a5dee4b472203212.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM2MDQyOTM4_size_16_color_FFFFFF_t_70 1]: /images/20230528/e343da27abe14e139227fa5df7095cb5.png [20200323150328720.png]: /images/20230528/63a8f8e4b34d41e6b7f57e8a5ffde93b.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM2MDQyOTM4_size_16_color_FFFFFF_t_70 2]: /images/20230528/dfc820d8fa07406abcf8dfc161956f52.png [20200323153346738.png]: /images/20230528/82115a7a56ef4a57bec67b8f7fdd18c6.png
相关 Java 线程池、Runnable线程池、Callable线程池 线程池: 其实就是一个容纳多个线程的容器,其中的线程可以反复的使用,省去了频繁创建和销毁过程对象的操作,无需反复创建线程面消耗过多资源。 为什么要用线程池: 合理 青旅半醒/ 2023年02月26日 12:30/ 0 赞/ 53 阅读
相关 线程、线程池 创建线程的3种方法: package com.frank.threadPool.createThread; / @author 小石潭记 布满荆棘的人生/ 2022年10月22日 04:27/ 0 赞/ 387 阅读
相关 线程池 1.所谓线程池,就是程序的初始化阶段,就预先创建一批线程,每个线程都做好准备干活; 2.然后有一个任务列表,一开始为空,当有任务来了,就往任务列表里面添加;这个任务列表 痛定思痛。/ 2022年06月13日 13:22/ 0 赞/ 330 阅读
相关 线程池 西施越溪女,明艳光云海 最近用线程池和不用线程池做了个速度的测试,在这里备注下: 结果是速度不相上下; public static void main(Str 妖狐艹你老母/ 2022年05月20日 02:35/ 0 赞/ 284 阅读
相关 线程池 线程池 Java里面线程池的顶级接口是 java.util.concurrent.Executor , 但是严格意义上讲 Executor并不是一个线程池,而只是一个 迈不过友情╰/ 2022年03月06日 14:34/ 0 赞/ 402 阅读
相关 线程池 线程池 > 从字面义上来讲,是指管理一组同构工作线程的资源池。线程池是与工作队列密切相关的,其中在工作队列中(Worker Queue)保存了所有等待执行的任务。工作者( 清疚/ 2021年12月11日 03:35/ 0 赞/ 389 阅读
相关 线程池 可preStart一个或全部core thread 0,小于core则来一个任务建一个线程(firstTask),队列,额外线程,拒绝 一个AtomicInteger的 今天药忘吃喽~/ 2021年11月23日 03:40/ 0 赞/ 412 阅读
相关 线程池 1、先创建线程池 import java.util.concurrent.ArrayBlockingQueue; import java.util.concu 拼搏现实的明天。/ 2021年11月09日 14:28/ 0 赞/ 422 阅读
还没有评论,来说两句吧...