溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Java線程池的實(shí)現(xiàn)方法

發(fā)布時間:2021-07-20 11:47:07 來源:億速云 閱讀:156 作者:chen 欄目:編程語言

本篇內(nèi)容主要講解“Java線程池的實(shí)現(xiàn)方法”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“Java線程池的實(shí)現(xiàn)方法”吧!

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

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

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

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

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

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

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

◆ T3 線程銷毀的時間

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

可以看出T1,T3是多線程本身的帶來的開銷,我們渴望減少T1,T3所用的時間,從而減少T的時間。但一些線程的使用者并沒有注意到 這一點(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ù),從而提高服務(wù)器程序性能的。它把T1,T3分別安排在服務(wù)器程序的啟動和結(jié)束的時間段或者一些空閑的時間段,這樣在服務(wù)器程序處理客戶請求時,不會有T1,T3的開銷了。

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

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

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

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

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

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

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

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

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

public class ThreadPoolManager {      private static ThreadPoolManager instance = null;      private List<Upload> taskQueue = Collections.synchronizedList(new LinkedList<Upload>());//任務(wù)隊(duì)列      private WorkThread[] workQueue ;    //工作線程(真正執(zhí)行任務(wù)的線程)      private static int worker_num = 5;    //工作線程數(shù)量(默認(rèn)工作線程數(shù)量是5)      private static int worker_count = 0;            private ThreadPoolManager(){          this(5);      }      private ThreadPoolManager(int num){          worker_num = num;          workQueue = new WorkThread[worker_num];          for(int i=0;i<worker_num;i++){              workQueue[i] = new WorkThread(i);          }      }            public static synchronized ThreadPoolManager getInstance(){          if(instance==null)              instance = new ThreadPoolManager();          return instance;      }            public void addTask(Upload task){          //對任務(wù)隊(duì)列的操作要上鎖          synchronized (taskQueue) {              if(task!=null){                  taskQueue.add(task);                  taskQueue.notifyAll();                  System.out.println("task id "+task.getInfo() + " submit!");              }                            }      }            public void BatchAddTask(Upload[] tasks){          //對任務(wù)隊(duì)列的修改操作要上鎖          synchronized (taskQueue) {              for(Upload e:tasks){                  if(e!=null){                      taskQueue.add(e);                      taskQueue.notifyAll();                      System.out.println("task id "+e.getInfo() + " submit!");                  }              }                  }      }            public void destory(){          System.out.println("pool begins to destory ...");          for(int i = 0;i<worker_num;i++){              workQueue[i].stopThread();              workQueue[i] = null;          }          //對任務(wù)隊(duì)列的操作要上鎖          synchronized (taskQueue) {              taskQueue.clear();          }                    System.out.println("pool ends to destory ...");      }            private class WorkThread extends Thread{          private int taksId ;          private boolean isRuning = true;          private boolean isWaiting = false;                                         public WorkThread(int taskId){              this.taksId= taskId;              this.start();          }                    public boolean isWaiting(){              return isWaiting;          }          // 如果任務(wù)進(jìn)行中時,不能立刻終止線程,需要等待任務(wù)完成之后檢測到isRuning為false的時候,退出run()方法          public void stopThread(){              isRuning = false;          }                    @Override         public void run() {              while(isRuning){                  Upload temp = null;                  //對任務(wù)隊(duì)列的操作要上鎖                  synchronized (taskQueue) {                      //任務(wù)隊(duì)列為空,等待新的任務(wù)加入                      while(isRuning&&taskQueue.isEmpty()){                          try {                              taskQueue.wait(20);                          } catch (InterruptedException e) {                              System.out.println("InterruptedException occre...");                              e.printStackTrace();                          }                      }                      if(isRuning)                          temp = taskQueue.remove(0);                  }                  //當(dāng)?shù)却氯蝿?wù)加入時候,終止線程(調(diào)用stopThread函數(shù))造成 temp = null                  if(temp!=null){                      System.out.println("task info: "+temp.getInfo()+ " is begining");                      isWaiting = false;                      temp.uploadPic();                      isWaiting = true;                      System.out.println("task info: "+temp.getInfo()+ " is finished");                  }                  }          }      }  }

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

public abstract class Upload {      protected String info;      abstract boolean uploadPic();      public String getInfo(){          return info;      }  }

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

public class TaskUpload extends Upload {            public TaskUpload(String info){          this.info = info;      }      public String getInfo(){          return info;      }      @Override     public boolean uploadPic()  {          // TODO Auto-generated method stub          System.out.println(info+"sleep begin ....");          try {              Thread.sleep(2000);          } catch (InterruptedException e) {              // TODO Auto-generated catch block              e.printStackTrace();          }          System.out.println(info+"sleep end ....");          return false;      }  }

***,測試這個簡單的線程池:

public class ThreadPoolManagerTest {        public static void main(String[] args) {          // TODO Auto-generated method stub          Upload[] tasks = createBatchTask(7);          ThreadPoolManager pool = ThreadPoolManager.getInstance();          pool.BatchAddTask(tasks);          pool.destory();      }      private static Upload[] createBatchTask(int n){          Upload[] tasks = new TaskUpload[n];          for(int i = 0;i<n ;i++ ){              tasks[i] = new TaskUpload("task id is "+ i);          }          return tasks;      }  }

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

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

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

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

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

到此,相信大家對“Java線程池的實(shí)現(xiàn)方法”有了更深的了解,不妨來實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI