自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Java之線程池簡單實(shí)現(xiàn)

開發(fā) 后端
在面向?qū)ο缶幊讨?,?chuàng)建和銷毀對象是很費(fèi)時(shí)間的,因?yàn)閯?chuàng)建一個(gè)對象要獲取內(nèi)存資源或者其它更多資源。在Java中更是如此,虛擬機(jī)將試圖跟蹤每一個(gè)對象, 以便能夠在對象銷毀后進(jìn)行垃圾回收。如何利用已有對象來服務(wù)就是一個(gè)需要解決的關(guān)鍵問題,其實(shí)這就是一些"池化資源"技術(shù)產(chǎn)生的原因。

以前做的東西,實(shí)現(xiàn)一個(gè)簡單的多線程機(jī)制,開始之前,現(xiàn)說說原理性的東西吧,下面是我在ibm開發(fā)者上搜到的內(nèi)容

線程池的技術(shù)背景

在面向?qū)ο缶幊讨?,?chuàng)建和銷毀對象是很費(fèi)時(shí)間的,因?yàn)閯?chuàng)建一個(gè)對象要獲取內(nèi)存資源或者其它更多資源。在Java中更是如此,虛擬機(jī)將試圖跟蹤每一個(gè)對象, 以便能夠在對象銷毀后進(jìn)行垃圾回收。所以提高服務(wù)程序效率的一個(gè)手段就是盡可能減少創(chuàng)建和銷毀對象的次數(shù),特別是一些很耗資源的對象創(chuàng)建和銷毀。如何利用 已有對象來服務(wù)就是一個(gè)需要解決的關(guān)鍵問題,其實(shí)這就是一些"池化資源"技術(shù)產(chǎn)生的原因。

多線程技術(shù)主要解決處理器單元內(nèi)多個(gè)線程執(zhí)行的問題,它可以顯著減少處理器單元的閑置時(shí)間,增加處理器單元的吞吐能力。但如果對多線程應(yīng)用不當(dāng),會增加對單個(gè)任務(wù)的處理時(shí)間??梢耘e一個(gè)簡單的例子:

假設(shè)在一臺服務(wù)器完成一項(xiàng)任務(wù)的時(shí)間為T

◆  T1 創(chuàng)建線程的時(shí)間

◆ T2 在線程中執(zhí)行任務(wù)的時(shí)間,包括線程間同步所需時(shí)間

◆ T3 線程銷毀的時(shí)間

顯然T = T1+T2+T3。注意這是一個(gè)極度簡化的假設(shè)。

可以看出T1,T3是多線程本身的帶來的開銷,我們渴望減少T1,T3所用的時(shí)間,從而減少T的時(shí)間。但一些線程的使用者并沒有注意到 這一點(diǎn),所以在程序中頻繁的創(chuàng)建或銷毀線程,這導(dǎo)致T1和T3在T中占有相當(dāng)比例。顯然這是突出了線程的弱點(diǎn)(T1,T3),而不是優(yōu)點(diǎn)(并發(fā)性)。

線程池技術(shù)正是關(guān)注如何縮短或調(diào)整T1,T3時(shí)間的技術(shù),從而提高服務(wù)器程序性能的。它把T1,T3分別安排在服務(wù)器程序的啟動和結(jié)束的時(shí)間段或者一些空閑的時(shí)間段,這樣在服務(wù)器程序處理客戶請求時(shí),不會有T1,T3的開銷了。

線程池不僅調(diào)整T1,T3產(chǎn)生的時(shí)間段,而且它還顯著減少了創(chuàng)建線程的數(shù)目。在看一個(gè)例子:

假設(shè)一個(gè)服務(wù)器一天要處理50000個(gè)請求,并且每個(gè)請求需要一個(gè)單獨(dú)的線程完成。我們比較利用線程池技術(shù)和不利于線程池技術(shù)的服務(wù)器 處理這些請求時(shí)所產(chǎn)生的線程總數(shù)。在線程池中,線程數(shù)一般是固定的,所以產(chǎn)生線程總數(shù)不會超過線程池中線程的數(shù)目或者上限(以下簡稱線程池尺寸),而如果 服務(wù)器不利用線程池來處理這些請求則線程總數(shù)為50000。一般線程池尺寸是遠(yuǎn)小于50000。所以利用線程池的服務(wù)器程序不會為了創(chuàng)建50000而在處 理請求時(shí)浪費(fèi)時(shí)間,從而提高效率。

這些都是假設(shè),不能充分說明問題,下面我將討論線程池的簡單實(shí)現(xiàn)并對該程序進(jìn)行對比測試,以說明線程技術(shù)優(yōu)點(diǎn)及應(yīng)用領(lǐng)域。

一般一個(gè)簡單線程池至少包含下列組成部分

◆ 線程池管理器(ThreadPoolManager):用于創(chuàng)建并管理線程池

◆ 工作線程(WorkThread): 線程池中線程

◆ 任務(wù)接口(Task):每個(gè)任務(wù)必須實(shí)現(xiàn)的接口,以供工作線程調(diào)度任務(wù)的執(zhí)行。

◆ 任務(wù)隊(duì)列:用于存放沒有處理的任務(wù)。提供一種緩沖機(jī)制。

線程池管理器至少有下列功能:創(chuàng)建線程池,銷毀線程池,添加新任務(wù)。下面就是小弟的實(shí)現(xiàn),還是歡迎拍磚哈:

  1. public class ThreadPoolManager {  
  2.     private static ThreadPoolManager instance = null;  
  3.     private List<Upload> taskQueue = Collections.synchronizedList(new LinkedList<Upload>());//任務(wù)隊(duì)列  
  4.     private WorkThread[] workQueue ;    //工作線程(真正執(zhí)行任務(wù)的線程)  
  5.     private static int worker_num = 5;    //工作線程數(shù)量(默認(rèn)工作線程數(shù)量是5)  
  6.     private static int worker_count = 0;  
  7.       
  8.     private ThreadPoolManager(){  
  9.         this(5);  
  10.     }  
  11.     private ThreadPoolManager(int num){  
  12.         worker_num = num;  
  13.         workQueue = new WorkThread[worker_num];  
  14.         for(int i=0;i<worker_num;i++){  
  15.             workQueue[i] = new WorkThread(i);  
  16.         }  
  17.     }  
  18.       
  19.     public static synchronized ThreadPoolManager getInstance(){  
  20.         if(instance==null)  
  21.             instance = new ThreadPoolManager();  
  22.         return instance;  
  23.     }  
  24.       
  25.     public void addTask(Upload task){  
  26.         //對任務(wù)隊(duì)列的操作要上鎖  
  27.         synchronized (taskQueue) {  
  28.             if(task!=null){  
  29.                 taskQueue.add(task);  
  30.                 taskQueue.notifyAll();  
  31.                 System.out.println("task id "+task.getInfo() + " submit!");  
  32.             }  
  33.                   
  34.         }  
  35.     }  
  36.       
  37.     public void BatchAddTask(Upload[] tasks){  
  38.         //對任務(wù)隊(duì)列的修改操作要上鎖  
  39.         synchronized (taskQueue) {  
  40.             for(Upload e:tasks){  
  41.                 if(e!=null){  
  42.                     taskQueue.add(e);  
  43.                     taskQueue.notifyAll();  
  44.                     System.out.println("task id "+e.getInfo() + " submit!");  
  45.                 }  
  46.             }          
  47.         }  
  48.     }  
  49.       
  50.     public void destory(){  
  51.         System.out.println("pool begins to destory ...");  
  52.         for(int i = 0;i<worker_num;i++){  
  53.             workQueue[i].stopThread();  
  54.             workQueue[i] = null;  
  55.         }  
  56.         //對任務(wù)隊(duì)列的操作要上鎖  
  57.         synchronized (taskQueue) {  
  58.             taskQueue.clear();  
  59.         }  
  60.           
  61.         System.out.println("pool ends to destory ...");  
  62.     }  
  63.       
  64.     private class WorkThread extends Thread{  
  65.         private int taksId ;  
  66.         private boolean isRuning = true;  
  67.         private boolean isWaiting = false;  
  68.           
  69.           
  70.            
  71.         public WorkThread(int taskId){  
  72.             this.taksId= taskId;  
  73.             this.start();  
  74.         }  
  75.           
  76.         public boolean isWaiting(){  
  77.             return isWaiting;  
  78.         }  
  79.         // 如果任務(wù)進(jìn)行中時(shí),不能立刻終止線程,需要等待任務(wù)完成之后檢測到isRuning為false的時(shí)候,退出run()方法  
  80.         public void stopThread(){  
  81.             isRuning = false;  
  82.         }  
  83.           
  84.         @Override 
  85.         public void run() {  
  86.             while(isRuning){  
  87.                 Upload temp = null;  
  88.                 //對任務(wù)隊(duì)列的操作要上鎖  
  89.                 synchronized (taskQueue) {  
  90.                     //任務(wù)隊(duì)列為空,等待新的任務(wù)加入  
  91.                     while(isRuning&&taskQueue.isEmpty()){  
  92.                         try {  
  93.                             taskQueue.wait(20);  
  94.                         } catch (InterruptedException e) {  
  95.                             System.out.println("InterruptedException occre...");  
  96.                             e.printStackTrace();  
  97.                         }  
  98.                     }  
  99.                     if(isRuning)  
  100.                         temp = taskQueue.remove(0);  
  101.                 }  
  102.                 //當(dāng)?shù)却氯蝿?wù)加入時(shí)候,終止線程(調(diào)用stopThread函數(shù))造成 temp = null  
  103.                 if(temp!=null){  
  104.                     System.out.println("task info: "+temp.getInfo()+ " is begining");  
  105.                     isWaiting = false;  
  106.                     temp.uploadPic();  
  107.                     isWaiting = true;  
  108.                     System.out.println("task info: "+temp.getInfo()+ " is finished");  
  109.                 }      
  110.             }  
  111.         }  
  112.     }  

然后定義任務(wù)接口(Task):這里我定義的是上傳圖片的功能接口(這里用抽象類或者接口隨你自己)。

  1. public abstract class Upload {  
  2.     protected String info;  
  3.     abstract boolean uploadPic();  
  4.     public String getInfo(){  
  5.         return info;  
  6.     }  

然后定義具體任務(wù)類:我這里簡單,讓它睡眠2s。當(dāng)然你也可以定義很多實(shí)現(xiàn)Upload的任務(wù)類。

  1. public class TaskUpload extends Upload {  
  2.       
  3.     public TaskUpload(String info){  
  4.         this.info = info;  
  5.     }  
  6.     public String getInfo(){  
  7.         return info;  
  8.     }  
  9.     @Override 
  10.     public boolean uploadPic()  {  
  11.         // TODO Auto-generated method stub  
  12.         System.out.println(info+"sleep begin ....");  
  13.         try {  
  14.             Thread.sleep(2000);  
  15.         } catch (InterruptedException e) {  
  16.             // TODO Auto-generated catch block  
  17.             e.printStackTrace();  
  18.         }  
  19.         System.out.println(info+"sleep end ....");  
  20.         return false;  
  21.     }  

***,測試這個(gè)簡單的線程池:

  1. public class ThreadPoolManagerTest {  
  2.  
  3.  
  4.     public static void main(String[] args) {  
  5.         // TODO Auto-generated method stub  
  6.         Upload[] tasks = createBatchTask(7);  
  7.         ThreadPoolManager pool = ThreadPoolManager.getInstance();  
  8.         pool.BatchAddTask(tasks);  
  9.         pool.destory();  
  10.     }  
  11.     private static Upload[] createBatchTask(int n){  
  12.         Upload[] tasks = new TaskUpload[n];  
  13.         for(int i = 0;i<n ;i++ ){  
  14.             tasks[i] = new TaskUpload("task id is "+ i);  
  15.         }  
  16.         return tasks;  
  17.     }  

線程池技術(shù)適用范圍及應(yīng)注意的問題

線程池的應(yīng)用范圍:

1、需要大量的線程來完成任務(wù),且完成任務(wù)的時(shí)間比較短。 WEB服務(wù)器完成網(wǎng)頁請求這樣的任務(wù),使用線程池技術(shù)是非常合適的。因?yàn)閱蝹€(gè)任務(wù)小,而任務(wù)數(shù)量巨大,你可以想象一個(gè)熱門網(wǎng)站的點(diǎn)擊次數(shù)。 但對于長時(shí)間的任務(wù),比如一個(gè)Telnet連接請求,線程池的優(yōu)點(diǎn)就不明顯了。因?yàn)門elnet會話時(shí)間比線程的創(chuàng)建時(shí)間大多了。

2、對性能要求苛刻的應(yīng)用,比如要求服務(wù)器迅速相應(yīng)客戶請求。

3、接受突發(fā)性的大量請求,但不至于使服務(wù)器因此產(chǎn)生大量線程的應(yīng)用。突發(fā)性大量客戶請求,在沒有線程池情況下,將產(chǎn)生大量線程,雖然理論上大部分操作系統(tǒng)線程數(shù)目***值不是問題,短時(shí)間內(nèi)產(chǎn)生大量線程可能使內(nèi)存到達(dá)極限,并出現(xiàn)"OutOfMemory"的錯(cuò)誤。

原文鏈接:http://www.cnblogs.com/slider/archive/2012/01/16/2323895.html

【編輯推薦】

  1. Java回調(diào)函數(shù)的理解
  2. Java路線圖:甲骨文的兩年計(jì)劃
  3. Java 8將支持無符號整型
  4. 深入研究Java虛擬機(jī)的類加載機(jī)制
  5. Swing多線程編碼過程中的誤區(qū)
責(zé)任編輯:林師授 來源: slider的博客
相關(guān)推薦

2020-09-04 10:29:47

Java線程池并發(fā)

2013-05-23 15:59:00

線程池

2023-06-07 13:49:00

多線程編程C#

2021-09-11 07:32:15

Java線程線程池

2020-12-10 08:24:40

線程池線程方法

2018-10-31 15:54:47

Java線程池源碼

2020-03-05 15:34:16

線程池C語言局域網(wǎng)

2012-05-15 02:18:31

Java線程池

2012-02-29 13:26:20

Java

2024-01-29 15:54:41

Java線程池公平鎖

2021-05-26 11:30:24

Java線程池代碼

2020-10-19 10:01:12

Nodejs線程池設(shè)計(jì)

2015-08-20 09:17:36

Java線程池

2020-11-25 11:33:47

Java線程技術(shù)

2023-08-02 08:03:08

Python線程池

2023-11-22 08:37:40

Java線程池

2021-09-11 15:26:23

Java多線程線程池

2013-06-08 13:07:23

Java線程池調(diào)度器

2023-05-19 08:01:24

Key消費(fèi)場景

2024-05-06 11:19:20

內(nèi)存池計(jì)算機(jī)編程
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號