线程池 野性酷女 2022-01-05 11:51 257阅读 0赞 ## 线程池 ## ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MDk5MDgxOA_size_16_color_FFFFFF_t_70] **为什么要使用线程池?** 线程是处理器调度的基本单位。我们会为每一个请求都独立创建一个线程,而操作系统创建线程、切换线程状态、结束线程都要使用CPU进行调度。使用线程池能够更好对线程进行管理、复用等。 **JDK为我们提供了那些支持?** ScheduledThreadPoolExecutor ThreadPoolExecutor(最核心) ForkJoin Pool **ThreadPoolExecutor的结构** ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MDk5MDgxOA_size_16_color_FFFFFF_t_70 1] 核心属性: corePoolSize \#核心线程数 maxinmumPoolSize \#线程总数 非核心数=总数-核心数 keepAliveTime \#当前线程数大于核心线程数时 非核心线程的等待被执行的等待时间 TimeUnit unit \#时间单位 workQueue \#保存未被执行的任务队列 RejectedExecutionHandler \#拒绝处理器 **poolExecutor 线程池对象** submit(Callable x) execute(Runnable x) 将任务送入到任务队列 Runnable接口没有返回值,Callable有返回值 核心: 当前运行线程数 小于corePoolSize 任务直接交给核心线程进行执行(通过线程调度执行任务) 当前运行线程数 大于或等于 corePoolSize 任务且满足队列规则 任务将进入任务队列进行等待 当前运行线程数 大于或等于 corePoolSize 任务且不满足队列规则 任务进入非核心线程(这类线程有存活时间,不一定会执行成功) **任务队列(实现BlockingQueue接口)** SyschronousQueue:每一次add()插入 必须要等待相对删除/读取操作 ArrayBlockingQueue:数组的方式,大小创建后不能改变大小,具有阻塞特性。 LinkedBlockingQueue:无限容量 基于链表的形式 LinkedBlockingDeque :无限双端链表队列,可以从两头进行元素的读/取操作 PriorityBlockingQueue:按照优先级进行内部元素排序的无限队列。 LinkedTransferQueue:无限队列,先进先出,具有阻塞特性。 \#阻塞特性:当队列满了,便会阻塞等待,直到有元素出队,后续的元素才可以被加入队列。 **拒绝处理器** 适用:那些既不能进入核心线程、等待队列,也无法创建新的线程执行(即非核心线程),或者线程异常等。 CallerRunsPolicy:直接运行该任务的run方法,但不是在线程池内部 AbortPolicy:RejectedExecutionException异常抛出(默认) DiscardPolicy:不会做任何处理 DiscardOldestPolicy:检查等待队列 强行取出队列头部任务 进行执行 ## ForkJoin框架 ## ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MDk5MDgxOA_size_16_color_FFFFFF_t_70 2] ForkJoin采用“工作窃取模式”,当有新的任务它可以将其拆分成更小的任务去执行,之后将结果进行合并,得到最终的结果。这种思想,类似于map/reduce的分而治之的思想处理任务。 **ForJoin的简单实现** ForkJoinPool forkJoinPool = new ForkJoinPool();//实现ForkJoin 就必须有ForkJoinPool的支持 ForkJoinTask<Long> task = new ForkJoinWork(0L,10000000000L);//参数为起始值与结束值 Long invoke = forkJoinPool.invoke(task);#执行ForkJoin任务中的compute() **ForJoinTask**必须继承RecursiveTask(有返回值)或者 RecursiveAction (没有返回值) public class ForkJoinWork extends RecursiveTask<Long> { private Long start;//起始值 private Long end;//结束值 public static final Long critical = 100000L;//临界值 public ForkJoinWork(Long start, Long end) { this.start = start; this.end = end; } @Override protected Long compute() { //判断是否是拆分完毕 Long lenth = end - start; if(lenth<=critical){ //如果拆分完毕就相加 Long sum = 0L; for (Long i = start;i<=end;i++){ sum += i; } return sum; }else { //没有拆分完毕就开始拆分 Long middle = (end + start)/2;//计算的两个值的中间值 ForkJoinWork right = new ForkJoinWork(start,middle); right.fork();//拆分,并压入线程队列 ForkJoinWork left = new ForkJoinWork(middle+1,end); left.fork();//拆分,并压入线程队列 //合并 return right.join() + left.join(); } } } ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MDk5MDgxOA_size_16_color_FFFFFF_t_70_pic_center] [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MDk5MDgxOA_size_16_color_FFFFFF_t_70]: /images/20211229/033648673c454f39b802144918f9f907.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MDk5MDgxOA_size_16_color_FFFFFF_t_70 1]: /images/20211229/a4a58f4f1b104e8487a9fb1a0837a430.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MDk5MDgxOA_size_16_color_FFFFFF_t_70 2]: /images/20211229/666dbd42baa646b7b051fee69dae8b22.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MDk5MDgxOA_size_16_color_FFFFFF_t_70_pic_center]: /images/20211229/678f7ff03ce646be9566bcbf08e4cb9f.png
相关 Java 线程池、Runnable线程池、Callable线程池 线程池: 其实就是一个容纳多个线程的容器,其中的线程可以反复的使用,省去了频繁创建和销毁过程对象的操作,无需反复创建线程面消耗过多资源。 为什么要用线程池: 合理 青旅半醒/ 2023年02月26日 12:30/ 0 赞/ 50 阅读
相关 线程、线程池 创建线程的3种方法: package com.frank.threadPool.createThread; / @author 小石潭记 布满荆棘的人生/ 2022年10月22日 04:27/ 0 赞/ 384 阅读
相关 线程池 1.所谓线程池,就是程序的初始化阶段,就预先创建一批线程,每个线程都做好准备干活; 2.然后有一个任务列表,一开始为空,当有任务来了,就往任务列表里面添加;这个任务列表 痛定思痛。/ 2022年06月13日 13:22/ 0 赞/ 328 阅读
相关 线程池 西施越溪女,明艳光云海 最近用线程池和不用线程池做了个速度的测试,在这里备注下: 结果是速度不相上下; public static void main(Str 妖狐艹你老母/ 2022年05月20日 02:35/ 0 赞/ 279 阅读
相关 线程池 线程池 Java里面线程池的顶级接口是 java.util.concurrent.Executor , 但是严格意义上讲 Executor并不是一个线程池,而只是一个 迈不过友情╰/ 2022年03月06日 14:34/ 0 赞/ 400 阅读
相关 线程池 线程池 > 从字面义上来讲,是指管理一组同构工作线程的资源池。线程池是与工作队列密切相关的,其中在工作队列中(Worker Queue)保存了所有等待执行的任务。工作者( 清疚/ 2021年12月11日 03:35/ 0 赞/ 386 阅读
相关 线程池 可preStart一个或全部core thread 0,小于core则来一个任务建一个线程(firstTask),队列,额外线程,拒绝 一个AtomicInteger的 今天药忘吃喽~/ 2021年11月23日 03:40/ 0 赞/ 410 阅读
相关 线程池 1、先创建线程池 import java.util.concurrent.ArrayBlockingQueue; import java.util.concu 拼搏现实的明天。/ 2021年11月09日 14:28/ 0 赞/ 420 阅读
还没有评论,来说两句吧...