newCachedThreadPool缓存线程池 线程池之newCachedThreadPool可缓存线程池的实例

软件发布|下载排行|最新软件

当前位置:首页IT学院IT技术

newCachedThreadPool缓存线程池 线程池之newCachedThreadPool可缓存线程池的实例

格子间里格子衫   2021-06-19 我要评论
想了解线程池之newCachedThreadPool可缓存线程池的实例的相关内容吗,格子间里格子衫在本文为您仔细讲解newCachedThreadPool缓存线程池的相关知识和一些Code实例,欢迎阅读和指正,我们先划重点:线程池,newCachedThreadPool,可缓存线程池,下面大家一起来学习吧。

java线程池:

Java通过Executors提供四种线程池,分别为:

newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。

newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。

newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。

newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。

下面我们来分析newCachedThreadPool:

这种类型的线程池特点是:

工作线程的创建数量几乎没有限制(其实也有限制的,数目为Interger. MAX_VALUE), 这样可灵活的往线程池中添加线程。

如果长时间没有往线程池中提交任务,即如果工作线程空闲了指定的时间(默认为1分钟),则该工作线程将自动终止。终止后,如果你又提交了新的任务,则线程池重新创建一个工作线程。

在使用CachedThreadPool时,一定要注意控制任务的数量,否则,由于大量线程同时运行,很有会造成系统瘫痪。

public class ThreadPoolCached {
 public static void main(String[] args) {
  ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
  for (int i = 0; i < 10; i++) {
   final int index = i;
   try {
    Thread.sleep(index * 100);
   } catch (Exception e) {
    e.printStackTrace();
   }
 
   cachedThreadPool.execute(new Runnable() {
    @Override
    public void run() {
     System.out.println(index+"当前线程"+Thread.currentThread().getName());
    }
   });
  }
 }
 }

执行结果:

发现10个线程都是使用的线程1,线程池为无限大,当执行第二个任务时第一个任务已经完成,会复用执行第一个任务的线程,而不用每次新建线程。

newCachedThreadPool个人理解

先上源码

    public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }

特点:

1.核心线程数为零

2.最大线程数为无限

3.无任务时,线程存活的最大时间为60s

4.任务队列为同步移交队列,该队列没有缓冲区,即不会有任务会在该队列中排队,每当有任务要入队时,队列都会将任务移交给一个可用的线程

为什么叫缓存线程池,类比于redis缓存:

前者缓存的是频繁要用到的线程;后者缓存的是频繁要用到的数据

前者通过缓存线程,避免了每次执行任务都要创建、销毁线程的开销;后者通过缓存数据,避免了每次用到数据都要操作db

两者都有缓存失效的时间,前者对应keepAliveTime参数,超过该参数对应的时间后,销毁线程;后者当缓存对应的真实数据被修改时,缓存失效,清除数据

为了尽量重复利用缓存的线程,而不是每次要执行任务时创建新的线程,应尽量使执行任务的时间小于keepAliveTime参数,默认是60s

因为是一个“缓存”线程池,没有缓存可以永久有效,因此核心线程数为0。因此任务队列的缓冲区应为空,否则即便系统有可用的线程资源,当有新的任务时也不会被执行,而是进入任务队列排队直至队列满,这显然是不合理的。同样由于队列缓冲区为空,每来一个任务时,都会在必要时新建线程执行任务,这就有可能导致大量的线程被创建,进而系统瘫痪

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。

Copyright 2022 版权所有 软件发布 访问手机版

声明:所有软件和文章来自软件开发商或者作者 如有异议 请与本站联系 联系我们