美文网首页
Java 线程池ExecutorService 等待队列问题

Java 线程池ExecutorService 等待队列问题

作者: Eshin_Ye | 来源:发表于2019-09-30 11:12 被阅读0次
  • 1、首先看下Executor获取线程池,这样方式,可以设置线程池的大小,但是了解线程池的内部原理的情况下,这样的线程池可能会引起OOM,原因在于
    该线程池的等待队列最大长度默认为int的最大值,随口默写出来就是2147483647(2^31 -1,高中物理老师说过一句话,记住一些固定的数字可以预判一些问题)。线程池在提交任务时,如果线程池未达到最大线程数,则起线程执行任务,在达到最大值后,会放入等待队列,按默认的int最大值,很容易造成内存溢出。所以通常会选择自行构造线程池
ExecutorService threadPool = Executors.newFixedThreadPool(3);
  • 2、通过自行构建线程池,指定等待队列的长度。那么问题来了,虽然用的是BlockingQueue,但是往BlockingQueue放任务时,用的是offer(),方法,而不是阻塞的方法put();这样在队列满了之后,继续往队列放任务就会抛异常,线程池提供了rejection机制去处理这种情况,应用可以自定义如何处理队列满的情况,默认是直接丢弃。对于有些业务场景,我们宁愿阻塞等待,也不要无止境的放队列,然后让他失败。这时候需要再用一点奇技淫巧,用来保证在等待队列放置一定数量后,阻塞生成任务的线程,等到线程池里已经有任务处理完了再继续放入任务。
ExecutorService threadPool = new ThreadPoolExecutor(5, 5,
            0L, TimeUnit.MILLISECONDS,
            new ArrayBlockingQueue<Runnable>(5*2));
  • 3、还是使用2中自行构建的线程池,除此之外再定义一个blockQueue,最大长度为5,如下列代码。在while循环时,threadpool中的等待队列会逐渐增加最后稳定在5,并且此时与blockingQueue的长度一致,此时如果继续循环,便在blockingQueue.put(new Data())处阻塞,直到线程池中已有任务处理完。
BlockingQueue<Data> blockingQueue = new ArrayBlockingQueue<Data>(5);

    @Test
    public void testBlock() throws InterruptedException {
        int i=0;
        while(i<100){

            i++;
            blockingQueue.put(new Data());
//          System.out.println("blockingQueue.size():"+blockingQueue.size()+"  "+"threadpool:"+threadPool);
//          封装成task时并没有从blockingQueue中take,只有submit提交执行时才take,因此,等待队列中的task数目,就等于blockingQueue的长度了
            threadPool.submit( ()->{return process( blockingQueue.take());});
            System.out.println("blockingQueue.size():"+blockingQueue.size()+"  "+"threadpool:"+threadPool);
        }
        Thread.sleep(10000L);
        System.out.println("blockingQueue.size():"+blockingQueue.size()+"  "+"threadpool:"+threadPool);
    }


    public Result process(Data data) throws InterruptedException {
        Thread.sleep(300L);
        return new Result();
    }

相关文章

  • Java 线程池ExecutorService 等待队列问题

    1、首先看下Executor获取线程池,这样方式,可以设置线程池的大小,但是了解线程池的内部原理的情况下,这样的线...

  • Java并发 - 并发编程实战

    Java并发 - 线程Java并发 - 线程池Java并发 - Executor/ExecutorService/...

  • Java线程池ExecutorService中重要的方法

    ExecutorService 介绍 ExecutorService是java线程池定义的一个接口,它在java....

  • 线程池工作机制与原理

    书接上文, Java线程池 。接下来记录一下线程池的工作机制和原理 线程池的两个核心队列: 线程等待池,即线程队列...

  • ExecutorService

    ExecutorService扩展和实现Executor。 java 线程池的5种状态 RUNNING 线程池...

  • Java四大线程池

    Java通过Executors提供四种线程池,分别为: 获取线程池:ExecutorService pool= E...

  • java中创建线程池的方式

    创建线程池的方式: 使用Java提供的用于管理线程池的接口ExecutorService 创建线程池,共有四种方式...

  • jdk 线程池的源码分析

    先看看java线程池的应用:通过工具类来构建一个线程池 ExecutorService executorServi...

  • Java线程池ExecutorService

    之前一直都是听说xx框架内部使用线程池管理线程,优化的非常不错,然后本人对其的感觉就是嗯,没错,说的这么高大上肯定...

  • Java线程池ExecutorService

    简而言之,new Thread的弊端如下: 而使用线程池所带来的好处呢? 一:如何创建线程池。Java通过Exec...

网友评论

      本文标题:Java 线程池ExecutorService 等待队列问题

      本文链接:https://www.haomeiwen.com/subject/duxructx.html