成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Java線程池的那些事

開發 后端
熟悉java多線程的 朋友一定十分了解java的線程池,jdk中的核心實現類為java.util.concurrent.ThreadPoolExecutor。大家可能 了解到它的原理,甚至看過它的源碼;但是就像我一樣,大家可能對它的作用存在誤解。現在問題來了,jdk為什么要提供java線程池?使用java線程池 對于每次都創建一個新Thread有什么優勢?

熟悉java多線程的 朋友一定十分了解java的線程池,jdk中的核心實現類為java.util.concurrent.ThreadPoolExecutor。大家可能 了解到它的原理,甚至看過它的源碼;但是就像我一樣,大家可能對它的作用存在誤解。現在問題來了,jdk為什么要提供java線程池?使用java線程池 對于每次都創建一個新Thread有什么優勢?

 

Java線程池的那些事

對線程池的誤解

很長一段時間里我一直以為java線程池是為了提高多線程下創建線程的效率。創建好一些線程并緩存在線程池里,后面來了請求(Runnable)就 從連接池中取出一個線程處理請求;這樣就避免了每次創建一個新Thread對象。直到前段時間我看到一篇Neal Gafter(和Joshua Bloch合著了《Java Puzzlers》,現任職于微軟,主要從事.NET語言方面的工作)的訪談,里面有這么一段談話(http://www.infoq.com/cn/articles/neal-gafter-on-java):

淺談java線程池

乍一看,大神的思路就是不一樣:java線程池是為了防止java線程占用太多資源?

雖然是java大神的訪談,但是也不能什么都信,你說占資源就占資源?還是得寫測試用例測一下。

首先驗證下我的理解:

java線程池和創建java線程哪個效率高?

直接上測試用例:

 

  1. public class ThreadPoolTest extends TestCase { 
  2.     private static final int COUNT = 10000
  3.  
  4.     public void testThreadPool() throws InterruptedException { 
  5.         CountDownLatch countDownLatch = new CountDownLatch(COUNT); 
  6.         ExecutorService executorService = Executors.newFixedThreadPool(100); 
  7.         long bg = System.currentTimeMillis(); 
  8.         for (int i = 0; i < COUNT; i++) { 
  9.     Runnable command = new TestRunnable(countDownLatch); 
  10.     executorService.execute(command); 
  11.         } 
  12.         countDownLatch.await(); 
  13.         System.out.println("testThreadPool:" + (System.currentTimeMillis() - bg)); 
  14.     } 
  15.  
  16.     public void testNewThread() throws InterruptedException { 
  17.         CountDownLatch countDownLatch = new CountDownLatch(COUNT); 
  18.         long bg = System.currentTimeMillis(); 
  19.         for (int i = 0; i < COUNT; i++) { 
  20.     Runnable command = new TestRunnable(countDownLatch); 
  21.     Thread thread = new Thread(command); 
  22.     thread.start(); 
  23.         } 
  24.         countDownLatch.await(); 
  25.         System.out.println("testNewThread:" + (System.currentTimeMillis() - bg)); 
  26.     } 
  27.  
  28.     private static class TestRunnable implements Runnable { 
  29.         private final CountDownLatch countDownLatch; 
  30.  
  31.         TestRunnable(CountDownLatch countDownLatch) { 
  32.     this.countDownLatch = countDownLatch; 
  33.         } 
  34.  
  35.         @Override 
  36.         public void run() { 
  37.     countDownLatch.countDown(); 
  38.         } 
  39.     } 

這里使用Executors.newFixedThreadPool(100)是為了控制線程池的核心連接數和***連接數一樣大,都為100。

我的機子上的測試結果:

testThreadPool:31
testNewThread:624

可以看到,使用線程池處理10000個請求的處理時間為31ms,而每次啟用新線程的處理時間為624ms。

好了,使用線程池確實要比每次都創建新線程要快一些;但是testNewThread一共耗時624ms,算下平均每次請求的耗時為:

624ms/10000=62.4us

每次創建并啟動線程的時間為62.4微秒。根據80/20原理,這點兒時間根本可以忽略不計。所以線程池并不是為了效率設計的。

java線程池是為了節約資源?

再上測試用例:

 

  1. public class ThreadPoolTest extends TestCase { 
  2.     public void testThread() throws InterruptedException { 
  3.         int i = 1
  4.         while (true) { 
  5.     Runnable command = new TestRunnable(); 
  6.     Thread thread = new Thread(command); 
  7.     thread.start(); 
  8.     System.out.println(i++); 
  9.         } 
  10.     } 
  11.  
  12.     private static class TestRunnable implements Runnable { 
  13.         @Override 
  14.         public void run() { 
  15.     try { 
  16.         Thread.sleep(1000); 
  17.     } catch (InterruptedException e) { 
  18.         e.printStackTrace(); 
  19.     } 
  20.         } 
  21.     } 

以上用例模擬每次請求都創建一個新線程處理請求,然后默認每個請求的處理時間為1000ms。而在我的機子上當請求數達到1096時會內存溢出:

java.lang.OutOfMemoryError: unable to create new native thread

為什么會拋OOM Error呢?因為jvm會為每個線程分配一定內存(JDK5.0以后每個線程堆棧大小為1M,以前每個線程堆棧大小為256K,也可以通過jvm參數-Xss來設置),所以當線程數達到一定數量時就報了該error。

設想如果不使用java線程池,而為每個請求都創建一個新線程來處理該請求,當請求量達到一定數量時一定會內存溢出的;而我們使用java線程池的話,線程數量一定會<=maximumPoolSize(線程池的***線程數),所以設置合理的話就不會造成內存溢出。

現在問題明朗了:java線程池是為了防止內存溢出,而不是為了加快效率。

淺談java線程池

上文介紹了java線程池啟動太多會造成OOM,使用java線程池也應該設置合理的線程數數量;否則應用可能十分不穩定。然而該如何設置這個數量呢?我們可以通過這個公式來計算:

(MaxProcessMemory – JVMMemory – ReservedOsMemory) / (ThreadStackSize) = Max number of threads

  • MaxProcessMemory     進程***的內存

  • JVMMemory                 JVM內存

  • ReservedOsMemory     JVM的本地內存

  • ThreadStackSize            線程棧的大小

MaxProcessMemory

MaxProcessMemory:進程***的尋址空間,當然也不能超過虛擬內存和物理內存的總和。關于不同系統的進程可尋址的***空間,可參考下面表格:

Maximum Address Space Per Process

 

Operating System

Maximum Address Space Per Process

Redhat Linux 32 bit

2 GB

Redhat Linux 64 bit

3 GB

Windows 98/2000/NT/Me/XP

2 GB

Solaris x86 (32 bit)

4 GB

Solaris 32 bit

4 GB

Solaris 64 bit

Terabytes

JVMMemory

JVMMemory: Heap + PermGen,即堆內存和***代內存和(注意,不包括本地內存)。

ReservedOsMemory

ReservedOSMemory:Native heap,即JNI調用方法所占用的內存。

ThreadStackSize

ThreadStackSize:線程棧的大小,JDK5.0以后每個線程堆棧大小默認為1M,以前每個線程堆棧大小為256K;可以通過jvm參數-Xss來設置;注意-Xss是jvm的非標準參數,不強制所有平臺的jvm都支持。

如何調大線程數?

如果程序需要大量的線程,現有的設置不能達到要求,那么可以通過修改MaxProcessMemory,JVMMemory,ThreadStackSize這三個因素,來增加能創建的線程數:

  • MaxProcessMemory 使用64位操作系統

  • JVMMemory   減少JVMMemory的分配

  • ThreadStackSize  減小單個線程的棧大小

 

責任編輯:王雪燕 來源: oschina
相關推薦

2020-10-07 22:21:13

程序員技術線程

2020-11-29 17:03:08

進程線程協程

2015-05-28 14:02:09

JavaJava日志性

2011-12-02 10:32:23

Java

2014-06-06 16:08:17

初志科技

2011-09-19 15:40:35

2020-07-29 08:14:59

云計算云遷移IT

2021-05-17 08:18:35

Java內存模型JMM

2018-05-31 13:50:30

Java高并發

2017-05-15 21:50:54

Linux引號

2024-02-04 17:03:30

2011-05-19 16:47:50

軟件測試

2012-05-01 08:06:49

手機

2012-05-31 09:53:38

IT風云15年

2021-04-13 18:16:07

多線程安全代碼

2010-07-27 11:29:43

Flex

2012-07-13 00:03:08

WEB前端開發WEB開發

2017-11-28 15:24:14

ETA配送構造

2023-11-14 09:08:12

MySQL多表關聯

2021-08-30 12:05:46

Linux字節對齊代碼
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 在线精品一区二区 | 国产精品久久久久久二区 | 久久精品91久久久久久再现 | 国产成人在线观看免费 | 日韩久久中文字幕 | 国产精品久久久av | 久久久久无码国产精品一区 | 99热精品6| 欧美一级片| 亚洲成人自拍 | 在线看片国产 | 亚洲国产高清在线观看 | 日本久久福利 | 日韩一区二区三区在线观看 | 91在线视频网址 | 久久33 | 三级av在线 | 成人精品国产一区二区4080 | 国产精品3区 | 免费观看av | 精品一二三区在线观看 | 欧美午夜精品理论片a级按摩 | 中文字幕精品一区二区三区精品 | 在线色网| 国产精品乱码一区二三区小蝌蚪 | 91精品一区二区三区久久久久 | 国产精品成人一区二区三区夜夜夜 | 欧美 日韩 国产 成人 | 日本一区二区高清视频 | 国产视频中文字幕 | 黄色在线免费网站 | 国产精品日日做人人爱 | 精品国产一区二区三区在线观看 | 色吧综合网 | 一区二区三区在线 | 国产一区999 | 久久久女 | 日韩电影免费在线观看中文字幕 | 国产一区二区三区免费视频 | 免费在线观看一区二区 | 一级毛片免费看 |