资讯专栏INFORMATION COLUMN

限制Java线程池运行线程以及等待线程数量的策略

Clect / 1920人阅读

摘要:限制线程池运行线程以及等待线程数量的策略对于所提供的,可以保证可以在内存中有固定数量的线程数运行。指的是当线程池拒绝该任务的时候,线程在本地线程直接。由此限制了线程池的等待线程数与执行线程数

限制Java线程池运行线程以及等待线程数量的策略

对于java.util.concurrent.Executors所提供的FixedThreadPool,可以保证可以在内存中有固定数量的线程数运行。但是由于FixedThreadPool绑定的是LinkedBlockingQueue。队列的上限没有限制(默认上限为Integer.MAX_VALUE),不断的提交新的线程,会造成任务在内存中长时间的堆积。

我们有可能面临如下的场景,主线程不断地提交任务线程,希望有固定数量的在线程中运行,也不想造成线程在内存中大量的等待堆积。由此需要我们自己定义一个线程池策略。ThreadPoolExecutor为我们线程池的设置提供了很大的灵活性。

首先看FixedThreadPool的实现:

    public static ExecutorService More ...newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
            return new ThreadPoolExecutor(nThreads, nThreads,
                                          0L, TimeUnit.MILLISECONDS,
                                          new LinkedBlockingQueue(),
                                          threadFactory);
        }

可以看到,FixedThreadPool绑定的是LinkedBlockingQueue。我们需要做的第一个改造就是绑定有大小上线的BlockingQueue,在我的实现中绑定ArrayBlockingQueue并设置了size。

第二个是采用CallerRunsPolicy。ThreadPoolExecutor可以定义不同的任务拒绝策略。CallerRunsPolicy指的是当线程池拒绝该任务的时候,线程在本地线程直接execute。这样就限制了本地线程的循环提交流程。

    BlockingQueue workingQueue = new ArrayBlockingQueue(10);
    RejectedExecutionHandler rejectedExecutionHandler =
        new ThreadPoolExecutor.CallerRunsPolicy();
    ExecutorService threadPool = new ThreadPoolExecutor(10, 10, 0L, TimeUnit.MILLISECONDS,
        workingQueue, rejectedExecutionHandler);

    for (int i = 0; i < 100; i++) {
      
      threadPool.submit(new Callable() {

        @Override
        public Boolean call() throws Exception {
          System.out.println("thread " + String.valueOf(threadNo) + " is called");
          Thread.sleep(10000);
          System.out.println("thread " + String.valueOf(threadNo) + " is awake");
          throw new Exception();
        }

      });
    }

代码中定义了大小为10的线程池,for循环提交了20个线程的时候,10个执行线程,10个线程放入了workingQueue。当提交到第21个线程的时候,会触发RejectedExecutionHandler。在这里我们配置了CallerRunsPolicy策略。所以会在主线程直接执行该线程。也就是说,在本程序中最多会有11个线程在执行,10个线程在等待。由此限制了线程池的等待线程数与执行线程数

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/64881.html

相关文章

  • 美团面试题:Java-线程 ThreadPool 专题详解

    摘要:去美团面试,问到了什么是线程池,如何使用,为什么要用以下做个总结。二线程池线程池的作用线程池作用就是限制系统中执行线程的数量。真正的线程池接口是。创建固定大小的线程池。此线程池支持定时以及周期性执行任务的需求。 去美团面试,问到了什么是线程池,如何使用,为什么要用,以下做个总结。关于线程之前也写过一篇文章《高级面试题总结—线程池还能这么玩?》 1、什么是线程池:  java.util...

    enrecul101 评论0 收藏0
  • 美团面试题:Java-线程 ThreadPool 专题详解

    摘要:去美团面试,问到了什么是线程池,如何使用,为什么要用以下做个总结。二线程池线程池的作用线程池作用就是限制系统中执行线程的数量。真正的线程池接口是。创建固定大小的线程池。此线程池支持定时以及周期性执行任务的需求。 去美团面试,问到了什么是线程池,如何使用,为什么要用,以下做个总结。关于线程之前也写过一篇文章《高级面试题总结—线程池还能这么玩?》 1、什么是线程池:  java.util...

    wujl596 评论0 收藏0
  • Java并发总结

    摘要:限期阻塞调用方法等待时间结束或线程执行完毕。终止状态线程执行完毕或出现异常退了。和都会检查线程何时中断,并且在发现中断时提前放回。工厂方法将线程池的最大大小设置为,而将基本大小设置为,并将超时大小设置为分钟。 wait()、notify()、notifyAll() Object是所有类的基类,它有5个方法组成了等待、通知机制的核心:notify()、notifyAll()、wait()...

    szysky 评论0 收藏0
  • Java 线程详解

    摘要:最近项目中越来越多需要异步调用的地方,系统中虽有线程池管理,但还有可优化的空间,通过分享该文章,帮助大家了解线程池,同时学习使用线程池开启线程需要注意的地方。没错,上述方法创建的线程池就是。线程池就是程序中的装修公司,代劳各种脏活累活。 最近项目中越来越多需要异步调用的地方,系统中虽有线程池管理,但还有可优化的空间,通过分享该文章,帮助大家了解线程池,同时学习使用线程池开启线程需要注意...

    fanux 评论0 收藏0
  • Java线程

    摘要:中的线程池是运用场景最多的并发框架。才是真正的线程池。存放任务的队列存放需要被线程池执行的线程队列。所以线程池的所有任务完成后,它最终会收缩到的大小。饱和策略一般情况下,线程池采用的是,表示无法处理新任务时抛出异常。 Java线程池 1. 简介 系统启动一个新线程的成本是比较高的,因为它涉及与操作系统的交互,这个时候使用线程池可以提升性能,尤其是需要创建大量声明周期很短暂的线程时。Ja...

    jerry 评论0 收藏0

发表评论

0条评论

Clect

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<