首页 > 编程语言 > 详细

Java基础——线程池

时间:2020-05-15 00:12:46      阅读:61      评论:0      收藏:0      [点我收藏+]

1、线程池

线程池是为了避免线程频繁的创建和销毁带来的性能消耗,而建立的一种池化技术,它是把已创建的线程放入“池”中,当有任务来临时就可以重用已有的线程,无需等待创建的过程,这样就可以有效提高程序的响应速度

阿里巴巴的《Java 开发手册》中是这样规定线程池的:线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式,这样的处理方式让写的读者更加明确线程池的运行规则,规避资源耗尽的风险

Executors 返回的线程池对象的弊端:

FixedThreadPool 和 SingleThreadPool:允许的请求队列长度为 Integer.MAX_VALUE,可能会堆积大量的请求,从而导致 OOM(内存用完)
CachedThreadPool 和 ScheduledThreadPool:允许的创建线程数量为 Integer.MAX_VALUE,可能会创建大量的线程,从而导致 OOM(内存用完)

Executors 的源码中Executors.newFixedThreadPool()、Executors.newSingleThreadExecutor() 和 Executors.newCachedThreadPool() 等方法的底层都是通过 ThreadPoolExecutor 实现的

 //创建一个可控最大并发数线程池,以共享的无界队列方式来运行这些线程(只有要请求的过来,就会在一个队列里等待执行)
public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }

//创建单线程化线程池
public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
    }

//创建可回收缓存线程池
public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }

//创建支持定时与周期性任务的线程池
public static ScheduledExecutorService newSingleThreadScheduledExecutor(ThreadFactory threadFactory) {
        return new DelegatedScheduledExecutorService
            (new ScheduledThreadPoolExecutor(1, threadFactory));
    }

ThreadPoolExecutor方法

 1 public ThreadPoolExecutor(int corePoolSize, //线程池的常驻核心线程数。如果设置为 0,则表示在没有任何任务时,销毁线程池;如果大于 0,即使没有任务时也会保证线程池的线程数量等于此值。但需要注意,此值如果设置的比较小,则会频繁的创建和销毁线程(创建和销毁的原因会在本课时的下半部分讲到);如果设置的比较大,则会浪费系统资源,所以开发者需要根据自己的实际业务来调整此值
 2                             int maximumPoolSize, //线程池在任务最多时,最大可以创建的线程数。官方规定此值必须大于 0,也必须大于等于 corePoolSize,此值只有在任务比较多,且不能存放在任务队列时,才会用到
 3                             long keepAliveTime, //线程的存活时间,当线程池空闲时并且超过了此时间,多余的线程就会销毁,直到线程池中的线程数量销毁的等于 corePoolSize 为止,如果 maximumPoolSize 等于 corePoolSize,那么线程池在空闲的时候也不会销毁任何线程
 4                             TimeUnit unit,//存活时间的单位,它是配合 keepAliveTime 参数共同使用的
 5                             BlockingQueue<Runnable> workQueue,//线程池执行的任务队列,当线程池的所有线程都在处理任务时,如果来了新任务就会缓存到此任务队列中排队等待执行
 6                             ThreadFactory threadFactory,//线程的创建工厂,此参数一般用的比较少,我们通常在创建线程池时不指定此参数,它会使用默认的线程创建工厂的方法来创建线程
 7                             RejectedExecutionHandler handler //指定线程池的拒绝策略,当线程池的任务已经在缓存队列 workQueue 中存储满了之后,并且不能创建新的线程来执行此任务时,就会用到此拒绝策略,它属于一种限流保护的机制
 8   ) {
 9       if (corePoolSize < 0 ||
10          maximumPoolSize <= 0 ||
11          maximumPoolSize < corePoolSize ||
12          keepAliveTime < 0)
13         throw new IllegalArgumentException();
14      if (workQueue == null || threadFactory == null || handler == null)
15          throw new NullPointerException();
16      this.corePoolSize = corePoolSize;
17      this.maximumPoolSize = maximumPoolSize;
18      this.workQueue = workQueue;
19      this.keepAliveTime = unit.toNanos(keepAliveTime);
20      this.threadFactory = threadFactory;
21      this.handler = handler;
22  }

 

Java基础——线程池

原文:https://www.cnblogs.com/carblack/p/12890029.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!