• 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);@Testpublic 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 线程池等待队列问题相关推荐

  1. 四种Java线程池用法解析

    四种Java线程池用法解析 本文为大家分析四种Java线程池用法,供大家参考,具体内容如下 http://www.jb51.net/article/81843.htm 1.new Thread的弊端 ...

  2. Java线程池使用与原理

    线程池是什么? 我们可以利用java很容易创建一个新线程,同时操作系统创建一个线程也是一笔不小的开销.所以基于线程的复用,就提出了线程池的概念,我们使用线程池创建出若干个线程,执行完一个任务后,该线程 ...

  3. Java线程池实现原理及其在美团业务中的实践

    来自:美团技术团队 随着计算机行业的飞速发展,摩尔定律逐渐失效,多核CPU成为主流.使用多线程并行计算逐渐成为开发人员提升服务器性能的基本武器.J.U.C提供的线程池ThreadPoolExecuto ...

  4. Java线程池了解一下

    前言 马上就要过年了,还在岗位上坚守"swimming"的小伙伴们顶住.博主给大家带来一篇线程池的基本使用解解闷. 为什么需要使用线程池 1.减少线程创建与切换的开销 在没有使用线 ...

  5. java线程池拒绝策略_Java核心知识 多线程并发 线程池原理(二十三)

    线程池做的工作主要是控制运行的线程的数量,处理过程中将任务放入队列,然后在线程创建后 启动这些任务,如果线程数量超过了最大数量超出数量的线程排队等候,等其它线程执行完毕, 再从队列中取出任务来执行.他 ...

  6. java 线程池原理分析

    一.为什么使用线程池 1.降低资源消耗,减少线程创建和销毁次数,每个工作线程可以重复利用,执行多个任务 2.可根据系统承受能力,调整工作线程的数目,防止消耗过多的内存 二.java 线程池使用 Exe ...

  7. 面试题:四种Java线程池用法解析 !=!=未看

    1.new Thread的弊端 执行一个异步任务你还只是如下new Thread吗? 1 2 3 4 5 6 7 8 new Thread(new Runnable() {   @Override   ...

  8. java 线程池ThreadPoolExecutor

    线程池 线程池的作用: 线程池作用就是限制系统中执行线程的数量. 根 据系统的环境情况,可以自动或手动设置线程数量,达到运行的最佳效果:少了浪费了系统资源,多了造成系统拥挤效率不高.用线程池控制线程数 ...

  9. 由浅入深理解Java线程池及线程池的如何使用

    前言 多线程的异步执行方式,虽然能够最大限度发挥多核计算机的计算能力,但是如果不加控制,反而会对系统造成负担.线程本身也要占用内存空间,大量的线程会占用内存资源并且可能会导致Out of Memory ...

最新文章

  1. soj1201- 约数
  2. Linux之服务器时间同步
  3. Jquery学习笔记:获取jquery对象的基本方法
  4. OpenShift上的无痛集装箱化JBoss通用贷款处理
  5. Python format 函数- Python零基础入门教程
  6. 曲线相似度衡量——曲线距离计算Fréchet distance详解与python计算
  7. 计算机的配置以及简单的操作
  8. Spring之代理模式实例
  9. HDU1465 不容易系列之一【递推】
  10. Matlab Tricks(一)—— figure(1)
  11. 【招聘】阿里2022届春招实习生 - 机器学习/NLP/CV等
  12. 最近开发了一个向QQ好友自动发送消息的程序
  13. 【高数】Abel定理,幂级数的和收敛半径,不同幂级数收敛半径的比较,缺项幂级数的解法
  14. 国产银河数学式电子计算机是属于,《世界上公认的第一台电子计算机.doc
  15. MyBase 与 HTML Help Workshop 编辑chm
  16. mac 语音召唤siri_在Mac上使用Siri可以做的11件事
  17. Shellshock漏洞复现
  18. 为什么要做业务全场景的梳理?
  19. android 老人机模式,如何将智能手机切换成老人机模式
  20. 爬虫_app 5.3 adb工具

热门文章

  1. Alist挂载本地磁盘
  2. ICRA人工智能挑战赛参赛准备(一)重刷系统
  3. 不要再问我怎么设置Postman的环境变量和全局变量了
  4. 职场“狡兔死走狗烹”的破解之道
  5. 加班,随笔(20090328)
  6. Flutter 3.X二维码扫描功能
  7. 内网渗透思考(实践)
  8. 声纹识别demo_声纹识别 · JD NeuHub API Documents
  9. js输出数字用千分号分隔的三种方法
  10. 如何看待2019年初多闪、马桶MT和聊天宝这三款社交APP同时发布