新聞中心
線(xiàn)程池是Java5提供的一個(gè)新技術(shù),方便我們快速簡(jiǎn)潔的定義線(xiàn)程池。包括如下:

諸如 Web 服務(wù)器、數(shù)據(jù)庫(kù)服務(wù)器、文件服務(wù)器或郵件服務(wù)器之類(lèi)的許多服務(wù)器應(yīng)用程序都面向處理來(lái)自某些遠(yuǎn)程來(lái)源的大量短小的任務(wù)。請(qǐng)求以某種方式到達(dá)服務(wù)器,這種方式可能是通過(guò)網(wǎng)絡(luò)協(xié)議(例如 HTTP、FTP 或 POP)、通過(guò) JMS 隊(duì)列或者可能通過(guò)輪詢(xún)數(shù)據(jù)庫(kù)。不管請(qǐng)求如何到達(dá),服務(wù)器應(yīng)用程序中經(jīng)常出現(xiàn)的情況是:?jiǎn)蝹€(gè)任務(wù)處理的時(shí)間很短而請(qǐng)求的數(shù)目卻是巨大的。
構(gòu)建服務(wù)器應(yīng)用程序的一個(gè)過(guò)于簡(jiǎn)單的模型應(yīng)該是:每當(dāng)一個(gè)請(qǐng)求到達(dá)就創(chuàng)建一個(gè)新線(xiàn)程,然后在新線(xiàn)程中為請(qǐng)求服務(wù)。實(shí)際上,對(duì)于原型開(kāi)發(fā)這種方法工作得很好,但如果試圖部署以這種方式運(yùn)行的服務(wù)器應(yīng)用程序,那么這種方法的嚴(yán)重不足就很明顯。每個(gè)請(qǐng)求對(duì)應(yīng)一個(gè)線(xiàn)程(thread-per-request)方法的不足之一是:為每個(gè)請(qǐng)求創(chuàng)建一個(gè)新線(xiàn)程的開(kāi)銷(xiāo)很大;為每個(gè)請(qǐng)求創(chuàng)建新線(xiàn)程的服務(wù)器在創(chuàng)建和銷(xiāo)毀線(xiàn)程上花費(fèi)的時(shí)間和消耗的系統(tǒng)資源要比花在處理實(shí)際的用戶(hù)請(qǐng)求的時(shí)間和資源更多。
除了創(chuàng)建和銷(xiāo)毀線(xiàn)程的開(kāi)銷(xiāo)之外,活動(dòng)的線(xiàn)程也消耗系統(tǒng)資源。在一個(gè) JVM 里創(chuàng)建太多的線(xiàn)程可能會(huì)導(dǎo)致系統(tǒng)由于過(guò)度消耗內(nèi)存而用完內(nèi)存或“切換過(guò)度”。為了防止資源不足,服務(wù)器應(yīng)用程序需要一些辦法來(lái)限制任何給定時(shí)刻處理的請(qǐng)求數(shù)目。
線(xiàn)程池為線(xiàn)程生命周期開(kāi)銷(xiāo)問(wèn)題和資源不足問(wèn)題提供了解決方案。通過(guò)對(duì)多個(gè)任務(wù)重用線(xiàn)程,線(xiàn)程創(chuàng)建的開(kāi)銷(xiāo)被分?jǐn)偟搅硕鄠€(gè)任務(wù)上。其好處是,因?yàn)樵谡?qǐng)求到達(dá)時(shí)線(xiàn)程已經(jīng)存在,所以無(wú)意中也消除了線(xiàn)程創(chuàng)建所帶來(lái)的延遲。這樣,就可以立即為請(qǐng)求服務(wù),使應(yīng)用程序響應(yīng)更快。而且,通過(guò)適當(dāng)?shù)卣{(diào)整線(xiàn)程池中的線(xiàn)程數(shù)目,也就是當(dāng)請(qǐng)求的數(shù)目超過(guò)某個(gè)閾值時(shí),就強(qiáng)制其它任何新到的請(qǐng)求一直等待,直到獲得一個(gè)線(xiàn)程來(lái)處理為止,從而可以防止資源不足。
Java5提供以下線(xiàn)程池:
緩存線(xiàn)程池(newCachedThreadPool),可以創(chuàng)建任意個(gè)線(xiàn)程,每個(gè)任務(wù)過(guò)來(lái)后都會(huì)創(chuàng)建一個(gè)線(xiàn)程,用于任務(wù)少,或執(zhí)行時(shí)間短的任務(wù),例如我們創(chuàng)建十個(gè)任務(wù),那么緩沖線(xiàn)程池將會(huì)創(chuàng)建十個(gè)線(xiàn)程來(lái)執(zhí)行。如下代碼:
- ExecutorService threadPool = Executors.newCachedThreadPool();
- for(int i=1; i<=10; i++){
- final int taskId = i;
- threadPool.execute(new Runnable(){
- public void run() {
- for(int i=1; i<=10; i++){
- System.out.println(Thread.currentThread().getName() + " is looping of " + i + " the task is " + taskId);
- try {
- Thread.sleep(20);
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
- });
- }
- System.out.println("add all of 10 task");
- threadPool.shutdown();
固定數(shù)量線(xiàn)程池(newFixedThreadPool)允許我們創(chuàng)建固定線(xiàn)程數(shù)量的線(xiàn)程池,如果任務(wù)數(shù)大于線(xiàn)程池中線(xiàn)程的數(shù)量,那么任務(wù)將等待,如下代碼:
- ExecutorService threadPool = Executors.newFixedThreadPool(3);
- for(int i=1; i<=10; i++){
- final int taskId = i;
- threadPool.execute(new Runnable(){
- public void run() {
- for(int i=1; i<=10; i++){
- System.out.println(Thread.currentThread().getName() + " is looping of " + i + " the task is " + taskId);
- try {
- Thread.sleep(20);
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
- });
- }
- System.out.println("add all of 10 task");
- threadPool.shutdown();
如何實(shí)現(xiàn)線(xiàn)程掛掉后重新啟動(dòng)(創(chuàng)建單一的線(xiàn)程池)newSingleThreadExecutor(),這樣線(xiàn)程池中只會(huì)有一個(gè)線(xiàn)程工作,當(dāng)線(xiàn)程失敗后會(huì)重新創(chuàng)建一個(gè)線(xiàn)程將失敗的線(xiàn)程替換掉。
定時(shí)器線(xiàn)程池(scheduleAtFixedRate)與定時(shí)器很類(lèi)似,可以指定線(xiàn)程池中線(xiàn)程在多長(zhǎng)時(shí)間后執(zhí)行,以及每個(gè)多長(zhǎng)時(shí)間執(zhí)行一次,代碼如下,可以模擬讓炸彈在6s后爆炸,并且每個(gè)2s炸一次:
- Executors.newScheduledThreadPool(3).scheduleAtFixedRate(
- // .schedule(
- new Runnable(){
- public void run() {
- System.out.println("boming");
- }
- }, 6, 2, TimeUnit.SECONDS);
- }
大家可以執(zhí)行代碼測(cè)試。
網(wǎng)頁(yè)題目:Java5線(xiàn)程池使用
分享URL:http://m.5511xx.com/article/cdejhci.html


咨詢(xún)
建站咨詢(xún)
