四种线程池的使⽤⽅式和区别详解
⼀、为什么要使⽤线程池
我们知道线程的并发操作,并不是真正的同时执⾏,⽽是通过CPU的上下⽂切换来执⾏。因为CPU切换的速度很快,以⾄于我们感觉不到,会造成在⼀种在同⼀时间内执⾏了多个操作的错觉。java线程池创建的四种
那么我们在使⽤多线程的时候,如果创建了⼤量的线程,就会造成CPU的频繁切换,反⽽导致效率降低,⽽线程的数量在显式创建线程时,其实是不可控的。另外,频繁的创建和销毁线程,也会造成较⼤的开销。所以,我们可以使⽤线程池来控制线程数量和减少线程频繁创建销毁的开销。
⼆、java中的四种线程池
单例线程池:wSingleThreadExecutor();
缓存线程池:wCachedThreadPool();
定长线程池:wFixedThreadPool(nThreads);
定时线程池:wScheduledThreadPool(corePoolSize);
1.单例线程池:
单例线程池,顾名思义就是线程池中只有⼀个⼯作线程执⾏任务。执⾏的是串⾏操作,按照顺序执⾏。
如果有其他请求任务时,此时线程没有空闲,就会将此任务放到队列中等待执⾏。那它的队列其实是⼀个⽆线⼤的队列,如果有⼤量的请求任务时,⼀个线程的执⾏速度是有限的,就有可能造成队列积压,甚⾄于导致OOM的问题。
2.缓存线程池:
这种线程池内部没有核⼼线程,在有新的任务的时候,如果存在空闲线程的话就⽤空闲线程来执⾏任务,如果没有空闲线程的话,就新建⼀个线程来执⾏任务,这个最⼤线程数是接近⽆限⼤的。
缓存线程池的优点是可以灵活的伸缩线程数,但是它存在的问题是有可能在⼤量请求的时候,创建了过多的线程,导致的效率低下,甚⾄OOM。
3.定长线程池:
定长线程池的核⼼线程数等于最⼤线程数,所以它的线程数是固定的,是我们通过传参来进⾏设置的。当任务⼤于核⼼线程数的时候,就会放到队列中等待。
定长线程池需要注意的问题和单例线程池类似,也是有可能造成队列积压,以⾄于导致OOM的问题,所以,我们在使⽤时要合理的设置线程数。
4.定时线程池:
定时线程池可以指定时间的执⾏周期,指定⼀段时间去调⽤⼀次。
任务队列会根据任务延时时间的不同进⾏排序,延时时间越短地就排在队列的前⾯,先被获取执⾏。也就是优先级队列,这种队列是⽤堆来构建的,在此不做详述。
三、线程池的使⽤⽅式
1.单例线程池:
scheduleWithFixedDelay⽅法。我们先来看看这两个⽅法的参数,两个⽅法的参数其实是⼀样的,依照顺序分别是:Runnable对象、第⼀次执⾏的延迟时间、两次执⾏间隔的延迟时间、时间单位。
那这两个⽅法有什么区别呢?
经测试得出,scheduleAtFixedRate⽅法是:程序以起始时间为准则,每隔指定时间执⾏⼀次,不受任务执⾏时间影响。如果是执⾏任务执⾏的时间⼤于间隔时间的话,它不会重新开启⼀个新的任务进⾏执⾏,⽽是等待原有任务执⾏完成,马上开启下⼀个任务进⾏执⾏。这个时候,执⾏间隔时间是被打乱的。
scheduleWithFixedDelay⽅法是以执⾏任务结束时间为准,执⾏任务结束后,延迟指定的时间后再继续执⾏下⼀个执⾏任务,它是不管执⾏任务执⾏时间的长短,都是在执⾏结束后延迟指定的时间再继续执⾏。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。