线程池默认多少个线程_我需要多少个线程?
線程池默認(rèn)多少個(gè)線程
這取決于您的應(yīng)用程序。 但是,對(duì)于那些希望對(duì)如何從生產(chǎn)站點(diǎn)購(gòu)買的所有昂貴內(nèi)核中擠出大量資金的人,請(qǐng)多多包涵,我將闡明圍繞多線程 Java應(yīng)用程序的奧秘。
內(nèi)容針對(duì)最典型的Java EE應(yīng)用程序進(jìn)行了“優(yōu)化”,該應(yīng)用程序具有Web前端,允許最終用戶在應(yīng)用程序內(nèi)發(fā)起許多小交易。 每個(gè)事務(wù)的很大一部分都在等待一些外部資源。 例如從數(shù)據(jù)庫(kù)或任何其他集成數(shù)據(jù)源返回的查詢。 但是大多數(shù)內(nèi)容也與其他應(yīng)用程序相關(guān)。 例如繁重的計(jì)算建模應(yīng)用程序或處理數(shù)據(jù)的批處理過程。
但是,讓我們從基礎(chǔ)開始。 在我們描述的應(yīng)用程序類型中,您傾向于有很多用戶與您的應(yīng)用程序進(jìn)行交互。 是成千上萬同時(shí)活動(dòng)的用戶還是成千上萬的用戶–所有這些用戶都希望應(yīng)用程序及時(shí)響應(yīng)他們。 這就是您對(duì)操作系統(tǒng)設(shè)計(jì)人員感激的地方。 在沒有人想到HTTP協(xié)議之前,這些家伙就已經(jīng)找到了解決這種需求的方法。
在您在軟件中創(chuàng)建更多線程然后基礎(chǔ)硬件可以同時(shí)執(zhí)行的情況下,使用的解決方案很有用。 在硬件級(jí)別上,您還具有線程。 例如您CPU上的內(nèi)核或具有超線程功能的虛擬化環(huán)境(如Intel)。 無論如何,我們手頭的應(yīng)用程序很容易產(chǎn)生比基礎(chǔ)硬件直接支持更多的軟件線程。 您的操作系統(tǒng)現(xiàn)在正在啟動(dòng)的內(nèi)容類似于簡(jiǎn)單的循環(huán)調(diào)度。 在此期間,每個(gè)軟件線程輪流執(zhí)行,稱為時(shí)間片,以在實(shí)際硬件上運(yùn)行。
時(shí)間分片允許所有線程進(jìn)行。 否則,很容易想象這樣一種情況,其中一個(gè)用戶發(fā)起了一項(xiàng)真正昂貴的任務(wù),而為其他用戶提供服務(wù)的所有其他線程卻挨餓了。
因此,我們正在經(jīng)歷這個(gè)驚人的時(shí)間切片。 那么將線程數(shù)設(shè)置為L(zhǎng)ARGE_NUMBER并完成該操作是否可行? 顯然沒有。 其中包括間接費(fèi)用,實(shí)際上甚至包括幾種間接費(fèi)用。 因此,為了在調(diào)整線程時(shí)做出明智的決定,讓我們介紹一下由LARGE_NUMBER個(gè)線程一一導(dǎo)致的問題。
注冊(cè)狀態(tài)保存/恢復(fù) 。 處理器寄存器確實(shí)包含很多狀態(tài)。 每當(dāng)調(diào)度程序移至下一個(gè)任務(wù)時(shí),哪個(gè)文件都會(huì)保存到緩存中。 然后在時(shí)間到來時(shí)恢復(fù)。 幸運(yùn)的是,調(diào)度程序分配的時(shí)間片相對(duì)較大。 因此,在多線程環(huán)境中,來往于注冊(cè)表的保存/還原開銷通常不會(huì)成為我們最卑鄙的敵人。
鎖 。 當(dāng)時(shí)間片被鎖持有線程占用時(shí),所有其他等待此特定鎖的線程現(xiàn)在都必須等待。 直到鎖持有者得到另一片和釋放鎖的機(jī)會(huì)。 因此,如果您正在進(jìn)行大量同步,請(qǐng)檢查線程在高負(fù)載下的行為。 由于鎖持有線程,您的同步代碼有可能導(dǎo)致更多上下文切換。 分析線程轉(zhuǎn)儲(chǔ)將是開始調(diào)查這一危險(xiǎn)的好地方。
釋放虛擬內(nèi)存 。 所有操作系統(tǒng)都利用交換到外部存儲(chǔ)的虛擬內(nèi)存。 通過在需要時(shí)將內(nèi)存中的最近最少使用(LRU)數(shù)據(jù)交換到磁盤驅(qū)動(dòng)器。 哪個(gè)好 但是,如果您現(xiàn)在正在使用有限的內(nèi)存運(yùn)行應(yīng)用程序,并且有很多線程在爭(zhēng)奪將其堆棧和私有數(shù)據(jù)放入內(nèi)存的空間,那么您可能會(huì)遇到問題。
在每個(gè)時(shí)間片回合中,您可能都有線程在外部存儲(chǔ)中交換數(shù)據(jù)。 這將大大降低應(yīng)用程序的性能。 尤其對(duì)于問題特別棘手的Java應(yīng)用程序。 每當(dāng)您開始交換堆時(shí),每次Full GC運(yùn)行都將花費(fèi)很長(zhǎng)時(shí)間。 一些專家建議關(guān)閉操作系統(tǒng)級(jí)別的交換功能。 在Linux發(fā)行版中,您可以通過swapoff –a實(shí)現(xiàn)此目的。
但是,好消息是,過去幾年該問題已大大減少。 兩者均具有廣泛的64位OS部署,從而允許更大的RAM和SSD取代全球各地的傳統(tǒng)旋轉(zhuǎn)磁盤。 但是要注意敵人,如果有疑問,請(qǐng)檢查進(jìn)程的頁面進(jìn)/出比例。
最后但并非最不重要的- 線程緩存狀態(tài) 。 在所有現(xiàn)代處理器中,您都在內(nèi)核旁邊構(gòu)建了緩存,從而使操作完成速度比RAM中的數(shù)據(jù)快100倍。 絕對(duì)很棒。 但是不妙的是,當(dāng)線程開始為這個(gè)極其有限的空間而戰(zhàn)時(shí)。 然后,負(fù)責(zé)清理的LRU算法再次開始清理緩存,為新數(shù)據(jù)騰出空間。 這可能是其時(shí)間片中輸入緩存的數(shù)據(jù)最后一個(gè)線程。 因此,您的線程最終可能會(huì)從緩存中清除彼此的數(shù)據(jù)。 再次造成了嚴(yán)重的問題。
如果您在Intel體系結(jié)構(gòu)上運(yùn)行,那么在這種情況下可能會(huì)幫助您的解決方案是Intel的VTune Performance Analyzer
因此,也許將LARGE_NUMBER個(gè)線程扔到您的應(yīng)用程序配置中并不是最明智的選擇。 但是在配置線程數(shù)時(shí)可以給出什么提示?
首先,可以將某些應(yīng)用程序配置為以等于基礎(chǔ)硬件線程的線程數(shù)運(yùn)行。 那里的典型Web應(yīng)用程序可能不是這種情況,但是肯定有很好的案例支持此策略。 請(qǐng)注意,當(dāng)您的線程在諸如關(guān)系數(shù)據(jù)庫(kù)之類的外部資源后面等待時(shí),這些線程將從循環(huán)調(diào)度中刪除。 因此,在典型的Java EE應(yīng)用程序中,具有比基礎(chǔ)硬件更多的線程并且仍在運(yùn)行時(shí)不會(huì)出現(xiàn)鎖爭(zhēng)用或其他問題的情況并不少見。
接下來,將您的線程劃分為用于不同目的的不同組是明智的。 典型的情況是將計(jì)算線程與I / O線程分開。 計(jì)算線程通常在大部分時(shí)間都處于繁忙狀態(tài),因此將其數(shù)量保持在底層硬件容量以下非常重要。 另一方面,I / O線程(例如需要數(shù)據(jù)庫(kù)往返的操作)大部分時(shí)間都在等待。 因此,不會(huì)過于頻繁地為爭(zhēng)取資源做出貢獻(xiàn)。 因此,使I / O線程(方式)的數(shù)量大于支持您的應(yīng)用程序的硬件線程的數(shù)量是安全的。
然后,應(yīng)最小化線程的創(chuàng)建和銷毀。 由于這些操作往往很昂貴,因此請(qǐng)查看合并解決方案。 您可能正在使用已經(jīng)內(nèi)置了線程池的Java EE基礎(chǔ)結(jié)構(gòu),或者可以查看java.util.concurrent.ThreadPoolExecutor之類的解決方案。 但是,當(dāng)您有時(shí)需要增加或減少線程數(shù)時(shí),也不要太害羞–只需避免在與下一個(gè)HTTP請(qǐng)求或JDBC連接一樣可預(yù)測(cè)的事件上創(chuàng)建和刪除它們。
作為最后的建議,我們將提供最重要的建議。 測(cè)量。 調(diào)整線程池的大小,并在負(fù)載下運(yùn)行應(yīng)用程序。 測(cè)量吞吐量和延遲。 然后進(jìn)行優(yōu)化以實(shí)現(xiàn)您的目標(biāo)。 然后再次測(cè)量。 沖洗并重復(fù)。 直到您對(duì)結(jié)果滿意為止。
不要對(duì)CPU的性能做任何假設(shè)。 如今,CPU中發(fā)生的魔力數(shù)量巨大。 還要注意,虛擬化和JIT運(yùn)行時(shí)優(yōu)化也會(huì)增加額外的復(fù)雜性。 但是這些將成為另一個(gè)話題。 如果您訂閱我們的Twitter feed ,將會(huì)及時(shí)收到通知。
在撰寫本文時(shí),以下資源被用作靈感來源:
- Arch Robinson的帖子,關(guān)于多少線程會(huì)影響性能
- 不同的Stackoverflow問題和評(píng)論:
- http://stackoverflow.com/questions/130506/how-many-threads-should-i-use-in-my-java-program
是的。 本文是有關(guān)我們?cè)趦?nèi)存泄漏以外的其他問題領(lǐng)域進(jìn)行研究的第一條提示。 但是我們尚無法預(yù)測(cè)是否以及何時(shí)將發(fā)布針對(duì)所有鎖定和緩存爭(zhēng)用問題的解決方案。 但是絕對(duì)有希望。
參考: 我需要多少個(gè)線程? 由我們的JCG合作伙伴 Nikita Salnikov Tarnovski在Plumbr Blog博客上獲得。
翻譯自: https://www.javacodegeeks.com/2013/01/how-many-threads-do-i-need.html
線程池默認(rèn)多少個(gè)線程
總結(jié)
以上是生活随笔為你收集整理的线程池默认多少个线程_我需要多少个线程?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 大番茄U盘装机系统要如何安装系统?大番茄
- 下一篇: 自定义注解 实现自定义消息_实现自定义的