1. websphere線程池在哪設置
主界面里有數據源設置,里邊有線程池的設置大小堆棧等信息
2. 線程池之ThreadPoolExecutor使用
ThreadPoolExecutor提供了四個構造方法:
我們以最後一個構造方法(參數最多的那個),對其參數進行解釋:
如果對這些參數作用有疑惑的請看 ThreadPoolExecutor概述 。
知道了各個參數的作用後,我們開始構造符合我們期待的線程池。首先看JDK給我們預定義的幾種線程池:
適用場景:可用於Web服務瞬時削峰,但需注意長時間持續高峰情況造成的隊列阻塞。
適用場景:快速處理大量耗時較短的任務,如Netty的NIO接受請求時,可使用CachedThreadPool。
咋一瞅,不就是newFixedThreadPool(1)嗎?定眼一看,這里多了一層包裝,這一層有什麼用呢,寫個dome來解釋一下:
對比可以看出,FixedThreadPool可以向下轉型為ThreadPoolExecutor,並對其線程池進行配置,而SingleThreadExecutor被包裝後,無法成功向下轉型。 因此,SingleThreadExecutor被定以後,無法修改,做到了真正的Single。
newScheledThreadPool調用的是ScheledThreadPoolExecutor的構造方法,而ScheledThreadPoolExecutor繼承了ThreadPoolExecutor,構造是還是調用了其父類的構造方法。
對於ScheledThreadPool本文不做描述,其特性請關注後續篇章。
以下是自定義線程池,使用了有界隊列,自定義ThreadFactory和拒絕策略的demo:
輸出結果如下:
其中線程線程1-4先佔滿了核心線程和最大線程數量,然後4、5線程進入等待隊列,7-10線程被直接忽略拒絕執行,等1-4線程中有線程執行完後通知4、5線程繼續執行。
多線程系列目錄(不斷更新中):
線程啟動原理
線程中斷機制
多線程實現方式
FutureTask實現原理
線程池之ThreadPoolExecutor概述
線程池之ThreadPoolExecutor使用
線程池之ThreadPoolExecutor狀態控制
線程池之ThreadPoolExecutor執行原理
線程池之ScheledThreadPoolExecutor概述
線程池的優雅關閉實踐
3. 什麼是線程池,如何使用,為什麼要用
線程池,thread pool,是一種線程使用模式,線程池維護著多個線程,等待著監督管理者分配可並發執行的任務。
功能:應用程序可以有多個線程,這些線程在休眠狀態中需要耗費大量時間來等待事件發生。其他線程可能進入睡眠狀態,並且僅定期被喚醒以輪循更改或更新狀態信息,然後再次進入休眠狀態。
為了簡化對這些線程的管理,.NET框架為每個進程提供了一個線程池,一個線程池有若干個等待操作狀態,當一個等待操作完成時,線程池中的輔助線程會執行回調函數。線程池中的線程由系統管理,程序員不需要費力於線程管理,可以集中精力處理應用程序任務。
(3)線程池web擴展閱讀:
應用范圍
1、需要大量的線程來完成任務,且完成任務的時間比較短。 WEB伺服器完成網頁請求這樣的任務,使用線程池技術是非常合適的。因為單個任務小,而任務數量巨大,你可以想像一個熱門網站的點擊次數。 但對於長時間的任務,比如一個Telnet連接請求,線程池的優點就不明顯了。因為Telnet會話時間比線程的創建時間大多了。
2、對性能要求苛刻的應用,比如要求伺服器迅速響應客戶請求。
3、接受突發性的大量請求,但不至於使伺服器因此產生大量線程的應用。突發性大量客戶請求,在沒有線程池情況下,將產生大量線程,雖然理論上大部分操作系統線程數目最大值不是問題,短時間內產生大量線程可能使內存到達極限,並出現"OutOfMemory"的錯誤。
4. 線程池企業級常規使用實例
多線程在學校的時候其實用的非常少,甚至幾乎用不到,但是在公司是不一樣的,用的非常多,畢竟用戶數據量十分的大,曾經實習我在一個項目裡面做過一個數據處理,是計算這人和人之間的關系度,從而推出哪幾個人的親密度達到要求,如果不用多線程,要把這一批數據計算完,那麼是需要大概一年時間,後來把時間縮短到了8天,降低了兩個數量級。
1、我一般是這樣用線程池的,首先建立一個池子,當然有時候有現成的池子給你用,看業務是自己創建還是用公共的。
private static final ExecutorService commentExecutor =new ThreadPoolExecutor(20, 20, 1L,
TimeUnit.MINUTES, new ArrayBlockingQueue<>(30), r ->new Thread(r,"comment")); //新建立一個池子,看業務哈,一般這樣是可以的,各個參數這里不展開說,後面會解釋的,看業務設計參數值;
2、然後往池子裡面提任務
List<T> commentInfos = Lists.newCopyOnWriteArrayList(); //一般情況下ArrayList就可以了,這是用guava的
commentExecutor.submit(() -> {
try {
commentInfos.add(buildComment(reqParam));
}catch (Exception e) {
logger.info("buildComment error", e);
}
})
buildComment(reqParam) 這個是執行任務的函數,計算完後結果放到了commentInfos 集合中;
如果是批量計算型任務,而且事先能知道批量數,可以結合CountDownLatch使用,目的可以通過它來控制所有線程計算完後再往下走;
也是比較常用的;
3、CountDownLatch 結合使用
try {
final CountDownLatch latch =new CountDownLatch(reqParam.getProctNos().size()); //事先獲取到批次
reqParam.getProctNos().forEach(p -> //遍歷
commentExecutor.submit(() -> { //每一個批次提交到池子裡面
try {
commentInfos.add(buildComment(p,reqParam)); //開始運算,運算的結果放到commentInfos
}catch (Exception e) {
logger.info("buildComment error", e);
}finally {
latch.countDown(); //每個線程完成就釋放掉一個latch
}
})
);
latch.await(); //等待所有的latch釋放掉,也就是每一個線程都執行完成
}catch (Exception e) {
logger.error("異常", e);
return WebResponse.fail(e.getMessage());
}finally {
logger.info("結果 commentInfos:{},計算耗時:{}", JsonUtil.encode(commentInfos), stopwatch.elapsed(TimeUnit.MILLISECONDS));
}
可能沒用過線程池的小夥伴第一次看有點不明白,沒關系,等以後工作中用到再翻翻就好了。
5. Tomcat使用線程池配置高並發連接
1:配置executor屬性
打開/conf/server.xml文件,在Connector之前配置一個線程池:
重要參數說明:name :共享線程池的名字。這是Connector為了共享線程池要引用的名字,該名字必須唯一。默認值:None; namePrefix :在JVM上,每個運行線程都可以有一個name 字元串。這一屬性為線程池中每個線程的name字元串設置了一個前綴,Tomcat將把線程號追加到這一前綴的後面。默認值:tomcat-exec-; maxThreads :該線程池可以容納的最大線程數。默認值:200; maxIdleTime :在Tomcat關閉一個空閑線程之前,允許空閑線程持續的時間(以毫秒為單位)。只有當前活躍的線程數大於minSpareThread的值,才會關閉空閑線程。默認值:60000(一分鍾)。 minSpareThreads :Tomcat應該始終打開的最小不活躍線程數。默認值:25。
2:配置Connector
重要參數說明:executor :表示使用該參數值對應的線程池; minProcessors :伺服器啟動時創建的處理請求的線程數; maxProcessors :最大可以創建的處理請求的線程數; acceptCount :指定當所有可以使用的處理請求的線程數都被使用時,可以放到處理隊列中的請求數,超過這個數的請求將不予處理。
一.Tomcat內存優化
Tomcat內存優化主要是對 tomcat 啟動參數優化,我們可以在 tomcat 的啟動腳本 catalina.sh 中設置JAVA_OPTS 參數。
1.JAVA_OPTS參數說明
現公司伺服器內存一般都可以加到最大2G ,所以可以採取以下配置:
在cygwin=false前添加
配置完成後可重啟Tomcat ,通過以下命令進行查看配置是否生效:
首先查看Tomcat 進程號:
result
我們可以看到Tomcat 進程號是27698 。
查看是否配置生效:
能在輸出的信息中找到Heap Configuration中看到MaxHeapSize 等參數已經生效。
二.Tomcat並發優化
1.Tomcat連接相關參數
在Tomcat 配置文件 server.xml 中的 配置中
1.參數說明
minProcessors :最小空閑連接線程數,用於提高系統處理性能,默認值為 10 maxProcessors :最大連接線程數,即:並發處理的最大請求數,默認值為 75 acceptCount :允許的最大連接數,應大於等於 maxProcessors ,默認值為 100 enableLookups :是否反查域名,取值為: true 或 false 。為了提高處理能力,應設置為 false connectionTimeout :網路連接超時,單位:毫秒。設置為 0 表示永不超時,這樣設置有隱患的。通常可設置為 30000 毫秒。其中和最大連接數相關的參數為maxProcessors 和 acceptCount 。如果要加大並發連接數,應同時加大這兩個參數。web server允許的最大連接數還受制於操作系統的內核參數設置,通常 Windows 是 2000 個左右, Linux是 1000 個左右。
2.Tomcat中的配置示例
2.調整連接器connector的並發處理能力
1.參數說明
maxThreads :客戶請求最大線程數 minSpareThreads :Tomcat初始化時創建的 socket 線程數 maxSpareThreads :Tomcat連接器的最大空閑 socket 線程數 enableLookups :若設為true, 則支持域名解析,可把 ip 地址解析為主機名 redirectPort :在需要基於安全通道的場合,把客戶請求轉發到基於SSL 的 redirectPort 埠 acceptAccount :監聽埠隊列最大數,滿了之後客戶請求會被拒絕(不能小於maxSpareThreads ) connectionTimeout :連接超時 minProcessors :伺服器創建時的最小處理線程數 maxProcessors :伺服器同時最大處理線程數 URIEncoding :URL統一編碼
2.Tomcat中的配置示例
3.Tomcat緩存優化
1.參數說明
compression :打開壓縮功能 compressionMinSize :啟用壓縮的輸出內容大小,這裡面默認為2KB compressableMimeType :壓縮類型 connectionTimeout :定義建立客戶連接超時的時間. 如果為 -1, 表示不限制建立客戶連接的時間
2.Tomcat中的配置示例
4.參考配置
1.舊有的配置
參考網路對伺服器做過如下配置,拿出來分享下:
後來發現在訪問量達到3 百萬多的時候出現性能瓶頸。
2.更改後的配置
6. 幾種開源Java Web容器線程池的實現方法簡介
其中Resin從V3.0後需要購買才能用於商業目的,而其他兩種則是純開源的。可以分別從他們的網站上下載最新的二進制包和源代碼。
作為Web容器,需要承受較高的訪問量,能夠同時響應不同用戶的請求,能夠在惡劣環境下保持較高的穩定性和健壯性。在HTTP伺服器領域,ApacheHTTPD的效率是最高的,也是最為穩定的,但它只能處理靜態頁面的請求,如果需要支持動態頁面請求,則必須安裝相應的插件,比如mod_perl可以處理Perl腳本,mod_python可以處理Python腳本。
上面介紹的三中Web容器,都是使用Java編寫的HTTP伺服器,當然他們都可以嵌到Apache中使用,也可以獨立使用。分析它們處理客戶請求的方法有助於了解Java多線程和線程池的實現方法,為設計強大的多線程伺服器打好基礎。
Tomcat是使用最廣的Java Web容器,功能強大,可擴展性強。最新版本的Tomcat(5.5.17)為了提高響應速度和效率,使用了Apache Portable Runtime(APR)作為最底層,使用了APR中包含Socket、緩沖池等多種技術,性能也提高了。APR也是Apache HTTPD的最底層。可想而知,同屬於ASF(Apache Software Foundation)中的成員,互補互用的情況還是很多的,雖然使用了不同的開發語言。
Tomcat 的線程池位於tomcat-util.jar文件中,包含了兩種線程池方案。方案一:使用APR的Pool技術,使用了JNI;方案二:使用Java實現的ThreadPool。這里介紹的是第二種。如果想了解APR的Pool技術,可以查看APR的源代碼。
ThreadPool默認創建了5個線程,保存在一個200維的線程數組中,創建時就啟動了這些線程,當然在沒有請求時,它們都處理等待狀態(其實就是一個while循環,不停的等待notify)。如果有請求時,空閑線程會被喚醒執行用戶的請求。
具體的請求過程是:服務啟動時,創建一個一維線程數組(maxThread=200個),並創建空閑線程(minSpareThreads=5個)隨時等待用戶請求。當有用戶請求時,調用 threadpool.runIt(ThreadPoolRunnable)方法,將一個需要執行的實例傳給ThreadPool中。其中用戶需要執行的實例必須實現ThreadPoolRunnable介面。 ThreadPool首先查找空閑的線程,如果有則用它運行要執行ThreadPoolRunnable;如果沒有空閑線程並且沒有超過 maxThreads,就一次性創建minSpareThreads個空閑線程;如果已經超過了maxThreads了,就等待空閑線程了。總之,要找到空閑的線程,以便用它執行實例。找到後,將該線程從線程數組中移走。接著喚醒已經找到的空閑線程,用它運行執行實例(ThreadPoolRunnable)。運行完ThreadPoolRunnable後,就將該線程重新放到線程數組中,作為空閑線程供後續使用。
由此可以看出,Tomcat的線程池實現是比較簡單的,ThreadPool.java也只有840行代碼。用一個一維數組保存空閑的線程,每次以一個較小步伐(5個)創建空閑線程並放到線程池中。使用時從數組中移走空閑的線程,用完後,再歸還給線程池。
7. 怎樣確定 Web 應用程序的線程池大小
在部署 web 應用到生產環境,或者在對 web 應用進行性能測試的時候,經常會有人問:如何決定 web 應用線程池大小?決定一個 IO 阻塞型 web 應用的線程池大小是一項很艱巨的任務。通常是通過進行大量的性能測試來完成。在一個 web 應用中同時擁有多個線程池會讓決定最優線程池大小的過程變得更加復雜。本文將就這個常見的問題進行一些討論和建議。
8. 需要創建一靜態 線程池 每來一個web請求 作為一個線程,放入池中處理業務流程
ThreadPoolExecutor .excute(new Thread(){
public void run(){
// 請求處理
}
});