校园春色亚洲色图_亚洲视频分类_中文字幕精品一区二区精品_麻豆一区区三区四区产品精品蜜桃

主頁 > 知識庫 > Java代碼構建一個線程池

Java代碼構建一個線程池

熱門標簽:騰訊地圖標注商戶改名注冊入駐 黃石智能營銷電銷機器人效果 電話機器人的特色和創新 怎樣把地圖標注出來 地圖標注人員兼職 漯河辦理400電話 淮南騰訊地圖標注 開封便宜外呼系統報價 商丘百應電話機器人有沒有效果
在現代的操作系統中,有一個很重要的概念――線程,幾乎所有目前流行的操作系統都支持線程,線程來源于操作系統中進程的概念,進程有自己的虛擬地址空間以及正文段、數據段及堆棧,而且各自占有不同的系統資源(例如文件、環境變量等等)。與此不同,線程不能單獨存在,它依附于進程,只能由進程派生。如果一個進程派生出了兩個線程,那這兩個線程共享此進程的全局變量和代碼段,但每個線程各擁有各自的堆棧,因此它們擁有各自的局部變量,線程在UNIX系統中還被進一步分為用戶級線程(由進程自已來管理)和系統級線程(由操作系統的調度程序來管理)。

  既然有了進程,為什么還要提出線程的概念呢?因為與創建一個新的進程相比,創建一個線程將會耗費小得多的系統資源,對于一些小型的應用,可能感覺不到這點,但對于那些并發進程數特別多的應用,使用線程會比使用進程獲得更好的性能,從而降低操作系統的負擔。另外,線程共享創建它的進程的全局變量,因此線程間的通訊編程會更將簡單,完全可以拋棄傳統的進程間通訊的IPC編程,而采用共享全局變量來進行線程間通訊。

  有了上面這個概念,我們下面就進入正題,來看一下線程池究竟是怎么一回事?其實線程池的原理很簡單,類似于操作系統中的緩沖區的概念,它的流程如下:先啟動若干數量的線程,并讓這些線程都處于睡眠狀態,當客戶端有一個新請求時,就會喚醒線程池中的某一個睡眠線程,讓它來處理客戶端的這個請求,當處理完這個請求后,線程又處于睡眠狀態。可能你也許會問:為什么要搞得這么麻煩,如果每當客戶端有新的請求時,我就創建一個新的線程不就完了?這也許是個不錯的方法,因為它能使得你編寫代碼相對容易一些,但你卻忽略了一個重要的問題――性能!就拿我所在的單位來說,我的單位是一個省級數據大集中的銀行網絡中心,高峰期每秒的客戶端請求并發數超過100,如果為每個客戶端請求創建一個新線程的話,那耗費的CPU時間和內存將是驚人的,如果采用一個擁有200個線程的線程池,那將會節約大量的的系統資源,使得更多的CPU時間和內存用來處理實際的商業應用,而不是頻繁的線程創建與銷毀。

  既然一切都明白了,那我們就開始著手實現一個真正的線程池吧,線程編程可以有多種語言來實現,例如C、C++、java等等,但不同的操作系統提供不同的線程API接口,為了讓你能更明白線程池的原理而避免陷入煩瑣的API調用之中,我采用了JAVA語言來實現它,由于JAVA語言是一種跨平臺的語言,因此你不必為使用不同的操作系統而無法編譯運行本程序而苦惱,只要你安裝了JDK1.2以上的版本,都能正確地編譯運行本程序。另外JAVA語言本身就內置了線程對象,而且JAVA語言是完全面像對象的,因此能夠讓你更清晰地了解線程池的原理,如果你注意看一下本文的標題,你會發現整個示例程序的代碼只有大約100行。

  本示例程序由三個類構成,第一個是TestThreadPool類,它是一個測試程序,用來模擬客戶端的請求,當你運行它時,系統首先會顯示線程池的初始化信息,然后提示你從鍵盤上輸入字符串,并按下回車鍵,這時你會發現屏幕上顯示信息,告訴你某個線程正在處理你的請求,如果你快速地輸入一行行字符串,那么你會發現線程池中不斷有線程被喚醒,來處理你的請求,在本例中,我創建了一個擁有10個線程的線程池,如果線程池中沒有可用線程了,系統會提示你相應的警告信息,但如果你稍等片刻,那你會發現屏幕上會陸陸續續提示有線程進入了睡眠狀態,這時你又可以發送新的請求了。

  第二個類是ThreadPoolManager類,顧名思義,它是一個用于管理線程池的類,它的主要職責是初始化線程池,并為客戶端的請求分配不同的線程來進行處理,如果線程池滿了,它會對你發出警告信息。

  最后一個類是SimpleThread類,它是Thread類的一個子類,它才真正對客戶端的請求進行處理,SimpleThread在示例程序初始化時都處于睡眠狀態,但如果它接受到了ThreadPoolManager類發過來的調度信息,則會將自己喚醒,并對請求進行處理。
   首先我們來看一下TestThreadPool類的源碼:


  //TestThreadPool.java
  1 import java.io.*;
  2
  3
  4 public class TestThreadPool
  5 {
  6 public static void main(String[] args)
  7 {
  8 try{
  9 BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
  10 String s;
  11 ThreadPoolManager manager = new ThreadPoolManager(10);
  12 while((s = br.readLine()) != null)
  13 {
  14 manager.process(s);
  15 }
  16 }catch(IOException e){}
  17 }
  18 }


  由于此測試程序用到了輸入輸入類,因此第1行導入了JAVA的基本IO處理包,在第11行中,我們創建了一個名為manager的類,它給ThreadPoolManager類的構造函數傳遞了一個值為10的參數,告訴ThreadPoolManager類:我要一個有10個線程的池,給我創建一個吧!第12行至15行是一個無限循環,它用來等待用戶的鍵入,并將鍵入的字符串保存在s變量中,并調用ThreadPoolManager類的process方法來將這個請求進行處理。

  下面我們再進一步跟蹤到ThreadPoolManager類中去,以下是它的源代碼:


  //ThreadPoolManager.java
  1 import java.util.*;
  2
  3
  4 class ThreadPoolManager
  5 {
  6
  7 private int maxThread;
  8 public Vector vector;
  9 public void setMaxThread(int threadCount)
  10 {
  11 maxThread = threadCount;
  12 }
  13
  14 public ThreadPoolManager(int threadCount)
  15 {
  16 setMaxThread(threadCount);
  17 System.out.println("Starting thread pool...");
  18 vector = new Vector();
  19 for(int i = 1; i = 10; i++)
  20 {
  21 SimpleThread thread = new SimpleThread(i);
  22 vector.addElement(thread);
  23 thread.start();
  24 }
  25 }
  26
  27 public void process(String argument)
  28 {
  29 int i;
  30 for(i = 0; i vector.size(); i++)
  31 {
  32 SimpleThread currentThread = (SimpleThread)vector.elementAt(i);
  33 if(!currentThread.isRunning())
  34 {
  35 System.out.println("Thread "+ (i+1) +" is processing:" +
  argument);
  36 currentThread.setArgument(argument);
  37 currentThread.setRunning(true);
  38 return;
  39 }
  40 }
  41 if(i == vector.size())
  42 {
  43 System.out.println("pool is full, try in another time.");
  44 }
  45 }
  46 }//end of class ThreadPoolManager


  我們先關注一下這個類的構造函數,然后再看它的process()方法。第16-24行是它的構造函數,首先它給ThreadPoolManager類的成員變量maxThread賦值,maxThread表示用于控制線程池中最大線程的數量。第18行初始化一個數組vector,它用來存放所有的SimpleThread類,這時候就充分體現了JAVA語言的優越性與藝術性:如果你用C語言的話,至少要寫100行以上的代碼來完成vector的功能,而且C語言數組只能容納類型統一的基本數據類型,無法容納對象。好了,閑話少說,第19-24行的循環完成這樣一個功能:先創建一個新的SimpleThread類,然后將它放入vector中去,最后用thread.start()來啟動這個線程,為什么要用start()方法來啟動線程呢?因為這是JAVA語言中所規定的,如果你不用的話,那這些線程將永遠得不到激活,從而導致本示例程序根本無法運行。
   下面我們再來看一下process()方法,第30-40行的循環依次從vector數組中選取SimpleThread線程,并檢查它是否處于激活狀態(所謂激活狀態是指此線程是否正在處理客戶端的請求),如果處于激活狀態的話,那繼續查找vector數組的下一項,如果vector數組中所有的線程都處于激活狀態的話,那它會打印出一條信息,提示用戶稍候再試。相反如果找到了一個睡眠線程的話,那第35-38行會對此進行處理,它先告訴客戶端是哪一個線程來處理這個請求,然后將客戶端的請求,即字符串argument轉發給SimpleThread類的setArgument()方法進行處理,并調用SimpleThread類的setRunning()方法來喚醒當前線程,來對客戶端請求進行處理。

  可能你還對setRunning()方法是怎樣喚醒線程的有些不明白,那我們現在就進入最后一個類:SimpleThread類,它的源代碼如下:

  //SimpleThread.java
  1 class SimpleThread extends Thread
  2 {
  3 private boolean runningFlag;
  4 private String argument;
  5 public boolean isRunning()
  6 {
  7 return runningFlag;
  8 }
  9 public synchronized void setRunning(boolean flag)
  10 {
  11 runningFlag = flag;
  12 if(flag)
  13 this.notify();
  14 }
  15
  16 public String getArgument()
  17 {
  18 return this.argument;
  19 }
  20 public void setArgument(String string)
  21 {
  22 argument = string;
  23 }
  24
  25 public SimpleThread(int threadNumber)
  26 {
  27 runningFlag = false;
  28 System.out.println("thread " + threadNumber + "started.");
  29 }
  30
  31 public synchronized void run()
  32 {
  33 try{
  34 while(true)
  35 {
  36 if(!runningFlag)
  37 {
  38 this.wait();
  39 }
  40 else
  41 {
  42 System.out.println("processing " + getArgument() + "... done.");
  43 sleep(5000);
  44 System.out.println("Thread is sleeping...");
  45 setRunning(false);
  46 }
  47 }
  48 } catch(InterruptedException e){
  49 System.out.println("Interrupt");
  50 }
  51 }//end of run()
  52 }//end of class SimpleThread

  如果你對JAVA的線程編程有些不太明白的話,那我先在這里簡單地講解一下,JAVA有一個名為Thread的類,如果你要創建一個線程,則必須要從Thread類中繼承,并且還要實現Thread類的run()接口,要激活一個線程,必須調用它的start()方法,start()方法會自動調用run()接口,因此用戶必須在run()接口中寫入自己的應用處理邏輯。那么我們怎么來控制線程的睡眠與喚醒呢?其實很簡單,JAVA語言為所有的對象都內置了wait()和notify()方法,當一個線程調用wait()方法時,則線程進入睡眠狀態,就像停在了當前代碼上了,也不會繼續執行它以下的代碼了,當調用notify()方法時,則會從調用wait()方法的那行代碼繼續執行以下的代碼,這個過程有點像編譯器中的斷點調試的概念。以本程序為例,第38行調用了wait()方法,則這個線程就像凝固了一樣停在了38行上了,如果我們在第13行進行一個notify()調用的話,那線程會從第38行上喚醒,繼續從第39行開始執行以下的代碼了。

  通過以上的講述,我們現在就不難理解SimpleThread類了,第9-14行通過設置一個標志runningFlag激活當前線程,第25-29行是SimpleThread類的構造函數,它用來告訴客戶端啟動的是第幾號進程。第31-50行則是我實現的run()接口,它實際上是一個無限循環,在循環中首先判斷一下標志runningFlag,如果沒有runningFlag為false的話,那線程處理睡眠狀態,否則第42-45行會進行真正的處理:先打印用戶鍵入的字符串,然后睡眠5秒鐘,為什么要睡眠5秒鐘呢?如果你不加上這句代碼的話,由于計算機處理速度遠遠超過你的鍵盤輸入速度,因此你看到的總是第1號線程來處理你的請求,從而達不到演示效果。最后第45行調用setRunning()方法又將線程置于睡眠狀態,等待新請求的到來。

  最后還有一點要注意的是,如果你在一個方法中調用了wait()和notify()函數,那你一定要將此方法置為同步的,即synchronized,否則在編譯時會報錯,并得到一個莫名其妙的消息:“current thread not owner”(當前線程不是擁有者)。

  至此為止,我們完整地實現了一個線程池,當然,這個線程池只是簡單地將客戶端輸入的字符串打印到了屏幕上,而沒有做任何處理,對于一個真正的企業級運用,本例還是遠遠不夠的,例如錯誤處理、線程的動態調整、性能優化、臨界區的處理、客戶端報文的定義等等都是值得考慮的問題,但本文的目的僅僅只是讓你了解線程池的概念以及它的簡單實現,如果你想成為這方面的高手,本文是遠遠不夠的,你應該參考一些更多的資料來深入地了解它。
您可能感興趣的文章:
  • java中通用的線程池實例代碼
  • Java 線程池詳解及實例代碼
  • 四種Java線程池用法解析
  • 深入java線程池的使用詳解
  • Java 線程池ExecutorService詳解及實例代碼
  • 支持生產阻塞的Java線程池
  • Java Socket編程實例(三)- TCP服務端線程池
  • 詳談Java幾種線程池類型介紹及使用方法
  • Java線程池的幾種實現方法和區別介紹
  • Java線程池使用與原理詳解

標簽:大興安嶺 拉薩 鄭州 馬鞍山 紅河 亳州 武威 岳陽

巨人網絡通訊聲明:本文標題《Java代碼構建一個線程池》,本文關鍵詞  Java,代碼,構建,一個,線程,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《Java代碼構建一個線程池》相關的同類信息!
  • 本頁收集關于Java代碼構建一個線程池的相關信息資訊供網民參考!
  • 推薦文章
    校园春色亚洲色图_亚洲视频分类_中文字幕精品一区二区精品_麻豆一区区三区四区产品精品蜜桃
    国产91在线看| 欧美日韩mp4| 欧美亚洲动漫精品| 26uuu精品一区二区| 18欧美亚洲精品| 狠狠色2019综合网| 欧美日韩视频一区二区| 日韩一区在线播放| 国产综合久久久久影院| 欧美日韩五月天| 一区二区三区在线观看网站| 国产一区二三区好的| 欧美视频一区二区在线观看| 国产精品蜜臀在线观看| 国产在线观看免费一区| 欧美一级欧美一级在线播放| 亚洲精品成人悠悠色影视| 成人性视频免费网站| 久久在线观看免费| 日本va欧美va精品发布| 欧美日本一区二区三区| 亚洲国产日产av| 欧美专区日韩专区| 一区二区三区资源| 日本韩国一区二区| 亚洲视频一区在线| 91在线码无精品| 成人免费一区二区三区在线观看| 国产高清不卡二三区| 国产喷白浆一区二区三区| 国产精品自在在线| 中文字幕av在线一区二区三区| 国产盗摄精品一区二区三区在线| 国产欧美日韩亚州综合 | 亚洲码国产岛国毛片在线| 国产成人一区二区精品非洲| 99久久99久久精品国产片果冻| 日韩欧美色综合网站| 亚洲一区二区黄色| 在线亚洲精品福利网址导航| ...av二区三区久久精品| 午夜影视日本亚洲欧洲精品| 激情六月婷婷综合| 中文字幕免费不卡在线| 国产精品一区二区三区99| 精品国产伦一区二区三区免费| 欧美aaa在线| 日韩精品在线网站| 国内精品久久久久影院色| 91精品国产综合久久香蕉麻豆| 视频一区欧美精品| 久久伊99综合婷婷久久伊| 国产盗摄精品一区二区三区在线 | 欧美精品在线视频| 亚洲成av人片| 欧美日韩一区二区三区视频| 午夜欧美大尺度福利影院在线看| 欧美三级日韩在线| 蜜臀av在线播放一区二区三区| 欧美另类z0zxhd电影| 亚洲综合免费观看高清完整版在线 | 另类欧美日韩国产在线| 555夜色666亚洲国产免| 激情伊人五月天久久综合| 久久久精品国产99久久精品芒果 | 国产福利精品一区二区| 久久精品水蜜桃av综合天堂| 色综合久久久久综合体| 亚洲一区在线播放| 日韩精品在线网站| 不卡av电影在线播放| 亚洲一区二区在线观看视频| 99热99精品| 亚洲综合色噜噜狠狠| 欧美一区午夜精品| 国产成人综合自拍| 一区二区高清视频在线观看| 日韩一区二区免费在线观看| 国产成人在线视频免费播放| 亚洲免费av观看| 精品三级在线看| 99re热视频这里只精品| 日本不卡不码高清免费观看| 日本一区二区三区视频视频| 在线亚洲精品福利网址导航| 午夜成人免费电影| 中文字幕亚洲区| 欧美一区二区三区小说| 成人久久18免费网站麻豆| 亚洲成人av电影在线| 国产日韩精品一区二区浪潮av | 一区二区欧美精品| 国产午夜精品一区二区三区视频| 日本丶国产丶欧美色综合| 国产在线精品免费| 国产精品传媒入口麻豆| 欧美剧在线免费观看网站| 国产精品自产自拍| 日韩电影在线看| 亚洲欧洲日韩一区二区三区| 欧美电视剧免费全集观看| 91啦中文在线观看| 国产一区欧美二区| 蜜桃一区二区三区在线观看| 亚洲男女毛片无遮挡| 久久午夜国产精品| 欧美一区二区三区在线| 在线视频国内自拍亚洲视频| 日本在线不卡一区| 中文字幕中文字幕一区| 欧美视频完全免费看| a4yy欧美一区二区三区| 精品一区二区精品| 肉肉av福利一精品导航| 夜色激情一区二区| 亚洲色图.com| 中文字幕日本乱码精品影院| 久久综合久久综合九色| 精品日本一线二线三线不卡| 欧美酷刑日本凌虐凌虐| fc2成人免费人成在线观看播放 | 日韩欧美卡一卡二| 欧美日韩五月天| 欧美视频一二三区| 99久久久久久99| 91在线观看成人| 97久久久精品综合88久久| 国产一区二区三区四区在线观看| 久久精品国产99国产| 美女国产一区二区| 久久99国产精品成人| 极品少妇一区二区三区精品视频| 蜜臀av一区二区| 国产一区二区不卡| 国产精品亚洲视频| 国产美女一区二区| 成人性生交大片免费看中文| 成人一级片在线观看| 不卡一区二区在线| 91成人在线精品| 欧美影院一区二区三区| 欧美日韩高清一区二区| 制服丝袜在线91| 欧美一级日韩免费不卡| 精品成人在线观看| 国产精品美女视频| 一区二区三区在线观看动漫| 亚洲午夜电影网| 久久99精品久久久久| 成人午夜碰碰视频| 91福利国产成人精品照片| 欧美日本一道本在线视频| 精品国产三级a在线观看| 国产人成一区二区三区影院| 中文字幕在线一区二区三区| 亚洲在线观看免费视频| 亚洲高清不卡在线| 成+人+亚洲+综合天堂| 欧美性色欧美a在线播放| 911国产精品| 国产日韩欧美电影| 亚洲夂夂婷婷色拍ww47| 狠狠色伊人亚洲综合成人| 成人深夜福利app| 欧美三区在线观看| 久久综合丝袜日本网| 国产丝袜在线精品| 亚洲成人精品在线观看| 久久精品av麻豆的观看方式| 成人性色生活片| 91精品国产全国免费观看| 国产午夜精品理论片a级大结局| 亚洲激情av在线| 久久er精品视频| 色婷婷综合久久久中文字幕| 日韩精品在线网站| 亚洲伦理在线免费看| 免费观看一级欧美片| 欧美日韩视频在线观看一区二区三区| 精品国产髙清在线看国产毛片| 综合久久久久综合| 激情伊人五月天久久综合| 欧美日韩一级二级三级| 中文字幕日韩av资源站| 狠狠色丁香久久婷婷综| 欧美日韩精品欧美日韩精品| 欧美精品一区二区久久久| 中文字幕一区二区三区四区不卡 | 午夜精品一区二区三区免费视频| 韩国理伦片一区二区三区在线播放| 欧美亚男人的天堂| 国产精品久久久久久久久搜平片| 免费在线观看一区二区三区| 在线免费亚洲电影| 国产精品免费观看视频| 精品亚洲成a人在线观看 | 亚洲一区二区三区四区五区中文 | 日本亚洲最大的色成网站www| 91社区在线播放| 久久婷婷国产综合精品青草|