1. 程式人生 > >使用無限大小執行緒池 newCachedThreadPool 可能遇到的問題

使用無限大小執行緒池 newCachedThreadPool 可能遇到的問題

看一段測試程式碼: 

[java] view plain copy  print?
  1. package com.wenniuwuren.concurrent;  
  2. import java.util.concurrent.ExecutorService;  
  3. import java.util.concurrent.Executors;  
  4. /** 
  5.  * Created by zhuyb on 16/6/16. 
  6.  */
  7. publicclass newCachedThreadPoolTest {  
  8.     publicstaticvoid main(String[] args) {  
  9.         ExecutorService executorService = Executors.newCachedThreadPool();  
  10.         for (int i = 1; i < 10000; i++)  
  11.             executorService.submit(new task());  
  12.     }  
  13. }  
  14. class task implements Runnable {  
  15.     @Override
  16.     publicvoid run() {  
  17.         try {  
  18.             Thread.sleep(5000);  
  19.         } catch (InterruptedException e) {  
  20.             e.printStackTrace();  
  21.         }  
  22.     }  
  23. }  

執行結果為:
[html] view plain copy  print?
  1. Exception in thread "main" java.lang.OutOfMemoryError: unable to create new native thread  
  2.     at java.lang.Thread.start0(Native Method)  
  3.     at java.lang.Thread.start(Thread.java:714)  
  4.     at java.util.concurrent.ThreadPoolExecutor.addWorker(ThreadPoolExecutor.java:950)  
  5.     at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1368)  
  6.     at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:112)  
  7.     at com.wenniuwuren.concurrent.newCachedThreadPoolTest.main(newCachedThreadPoolTest.java:15)  
  8.     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)  
  9.     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)  
  10.     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)  
  11.     at java.lang.reflect.Method.invoke(Method.java:497)  
  12.     at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)  
可以看出來是堆外記憶體溢位,因為我們新建的執行緒都在工作(程式碼中用sleep表示在工作中),newCachedThreadPool 只會重用空閒並且可用的執行緒,所以上述程式碼只能不停地建立新執行緒,在 64-bit JDK 1.7 中 -Xss 預設是 1024k,也就是 1M,那就是需要 10000*1M = 10G 的堆外記憶體空間來給執行緒使用,但是我的機器總共就 8G 記憶體,不夠建立新的執行緒,所以就 OOM 了。 總結一下:所以這個 newCachedThreadPool 大家一般不用就是這樣的原因,因為它的最大值是在初始化的時候設定為 Integer.MAX_VALUE,一般來說機器都沒那麼大記憶體給它不斷使用。當然知道可能出問題的點,就可以去重寫一個方法限制一下這個最大值,但是出於後期維護原因,一般來說用 newFixedThreadPool 也就足夠了。 

相關推薦

使用無限大小執行 newCachedThreadPool 可能遇到的問題

看一段測試程式碼:  [java] view plain copy  print? package com.wenniuwuren.concurrent;   import java.util.concurrent.ExecutorService;   i

Java四種執行newCachedThreadPool,newFixedThreadPool,newScheduledThreadPool,newSingle

轉自:https://www.cnblogs.com/baizhanshi/p/5469948.html 1、new Thread的弊端 執行一個非同步任務你還只是如下new Thread嗎? Java   1 2 3 4 5 6 7

[C++]固定大小執行

執行緒池模型 執行緒池是併發程式設計中常用的模型。 執行緒是一種非常寶貴的資源,建立、銷燬執行緒都是非常消耗時間的操作,所以我們的一個思路是在程式start up的時候,建立一個儲存有多個執行緒的快取,這樣程式執行時就不會頻繁的發生建立和銷燬執行緒的操作,從

如何合理設定執行大小

要想合理的配置執行緒池的大小,首先得分析任務的特性,可以從以下幾個角度分析: 任務的性質:CPU密集型任務、IO密集型任務、混合型任務。 任務的優先順序:高、中、低。 任務的執行時間:長、中、短。 任務的依賴性:是否依賴其他系統資源,如資料庫連線等。 性質不同的任務可

java執行newCachedThreadPool)的使用

import java.util.concurrent.*; /** * java執行緒池的使用 * 這個【可快取執行緒池】,沒看出來有什麼用呢。。。 */ public class Exe

Java多執行-----執行的使用,原理以及舉例實現(三)(四):使用樣例及如何配置執行大小

三.使用示例   前面我們討論了關於執行緒池的實現原理,這一節我們來看一下它的具體使用: public class Test { public static void main(String[] args) { ThreadPoolExe

執行大小設定,CPU的核心數、執行數的關係和區別,同步與堵塞完全是兩碼事

執行緒池應該設定多少執行緒合適,怎麼樣估算出來。最近接觸到一些相關資料,現作如下總結。 最開始接觸執行緒池的時候,沒有想到就僅僅是設定一個執行緒池的大小居然還有這麼多的學問,汗顏啊。 首先,需要考慮到執行緒池所進行的工作的性質: IO密集型 CPU密集型 簡單的分析來看,如果是CPU密集

ThreadLocal執行存在的問題,用TransmittableThreadLocal解決

總結:請使用TransmittableThreadLocal ThreadLocal是以執行緒為key的,而執行緒池裡面的執行緒是會被重新利用的,會導致ThreadLocal出現意料之外的事件。 比如可能會導致在SAAS中的串庫。 解決辦法如下: @Slf4j

ExecutorService常用方法和newFixedThreadPool建立固定大小執行

1、ExecutorService: 是一個介面,繼承了Executor: public interface ExecutorService extends Executor { } 2、Executor: 而Executor亦是一個介面,該介面只包含了一個方法: void exe

如何決定 Web 應用的執行大小

在部署 web 應用到生產環境,或者在對 web 應用進行效能測試的時候,經常會有人問:如何決定 web 應用執行緒池大小?決定一個 IO 阻塞型 web 應用的執行緒池大小是一項很艱鉅的任務。通常是通過進行大量的效能測試來完成。在一個 web 應用中同時擁有多個執行緒池會讓

java執行以及newCachedThreadPool使用過程中的問題

      為什麼要用執行緒池?原因很簡單,效能好,而且不用自己費心費力的管理執行緒       1、執行緒池基本說明及定義       從JDK 1.5開始,添加了Executors工具類,這個類定義了Executor、ExecutorService、ScheduledE

threadLocal執行導致區域性變數變化

這兩天一直在查無線app一個詭異的問題,表象是stg的介面返回資料,和線上介面的返回資料不一致。 1、初步判斷:有快取,檢視程式碼後發現快取時間直郵6分鐘,而且同一個介面,其他呼叫方的返回資料,stg和線上是保持一致的。 2、確認版本後,把線上版本和stg環境的版本號,進行多次check,發現版本是一致

ThreadPoolExecutor使用和思考(上)-執行大小設定與BlockingQueue的三種實現區別

工作中多處接觸到了ThreadPoolExecutor。趁著現在還算空,學習總結一下。 前記: jdk官方文件(javadoc)是學習的最好,最權威的參考。文章分上中下。上篇中主要介紹ThreadPoolExecutor接受任務相關的兩方面入參的意義和區別,池大小引

如何合理地估算執行大小

 這個問題雖然看起來很小,卻並不那麼容易回答。大家如果有更好的方法歡迎賜教,^_^     先來一個天真的估算方法:假設要求一個系統的TPS(Transaction Per Second或者Task Per Second)至少為20,然後假設每個Transaction由一個執行緒完成,繼續假設平均每個執行緒

如何合理確定執行大小

在java中,幾乎所有需要非同步或者併發執行任務的程式都可以使用執行緒池。在開發過程中,合理的使用執行緒池能夠帶來3個好處 首先是降低資源消耗。通過重複利用已建立的執行緒降低建立執行緒和銷燬執行緒所帶來的開銷。 提高相應速度。當任務到達時,任務可以不需要等待

java合理估算執行大小——Dark Magic

具體見併發程式設計網的文章http://ifeve.com/how-to-calculate-threadpool-size/, 原始碼亂序了,這裡做一個排序後分享 github地址: https://github.com/sunshanpeng/dark_magic

ThreadPoolExecutor執行大小設定

最近用到ThreadPoolExecutor ,想到這個問題; 下面是從網上找到的。 執行緒池的理想大小取決於被提交任務的型別以及所部署系統的特性。執行緒池應該避免設定的過大或過小,如果執行緒池過大,大量的執行緒將在相對很少的CPU和記憶體資源上發生競爭,這不僅

合理設定執行大小

開發十年,就只剩下這套架構體系了! >>>   

根據CPU核數合理設定執行大小

    自定義執行緒池程式碼 package com.lc.concurrent; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; i

如何用利特爾法則調整執行大小

## 利特爾法則 利特爾法則派生於**排隊論**,用以下數學公式表示: L = λW L 系統中存在的平均請求數量。 λ 請求有效到達速率。例如:5/s 表示每秒有5個請求到達系統。 W 請求在系統中的平均等待執行時間。 > 排隊論:研究服務系統中排隊現象隨機規律的學科,探究排隊有關的數