成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Java多線程設計模式之線程池模式

開發 后端
Worker Thread,該模式主要在于,事先啟動一定數目的工作線程。當沒有請求工作的時候,所有的工人線程都會等待新的請求過來,一旦有工作到達,就馬上從線程池中喚醒某個線程來執行任務,執行完畢后繼續在線程池中等待任務池的工作請求的到達。

 前序:

  Thread-Per-Message Pattern,是一種對于每個命令或請求,都分配一個線程,由這個線程執行工作。它將“委托消息的一端”和“執行消息的一端”用兩個不同的線程來實現。該線程模式主要包括三個部分:

  1,Request參與者(委托人),也就是消息發送端或者命令請求端

  2,Host參與者,接受消息的請求,負責為每個消息分配一個工作線程。

  3,Worker參與者,具體執行Request參與者的任務的線程,由Host參與者來啟動。

  由于常規調用一個方法后,必須等待該方法完全執行完畢后才能繼續執行下一步操作,而利用線程后,就不必等待具體任務執行完畢,就可以馬上返回繼續執行下一步操作。

  背景:

  由于在Thread-Per-Message Pattern中對于每一個請求都會生成啟動一個線程,而線程的啟動是很花費時間的工作,所以鑒于此,提出了Worker Thread,重復利用已經啟動的線程。

  線程池:

  Worker Thread,也稱為工人線程或背景線程,不過一般都稱為線程池。該模式主要在于,事先啟動一定數目的工作線程。當沒有請求工作的時候,所有的工人線程都會等待新的請求過來,一旦有工作到達,就馬上從線程池中喚醒某個線程來執行任務,執行完畢后繼續在線程池中等待任務池的工作請求的到達。

  任務池:主要是存儲接受請求的集合,利用它可以緩沖接受到的請求,可以設置大小來表示同時能夠接受最大請求數目。這個任務池主要是供線程池來訪問。

  線程池:這個是工作線程所在的集合,可以通過設置它的大小來提供并發處理的工作量。對于線程池的大小,可以事先生成一定數目的線程,根據實際情況來動態增加或者減少線程數目。線程池的大小不是越大越好,線程的切換也會耗時的。

  存放池的數據結構,可以用數組也可以利用集合,在集合類中一般使用Vector,這個是線程安全的。

  Worker Thread的所有參與者:

  1,Client參與者,發送Request的參與者

  2,Channel參與者,負責緩存Request的請求,初始化啟動線程,分配工作線程

  3,Worker參與者,具體執行Request的工作線程

  4,Request參與者

  注意:將在Worker線程內部等待任務池非空的方式稱為正向等待。

  將在Channel線程提供Worker線程來判斷任務池非空的方式稱為反向等待。

  線程池實例1:

  利用同步方法來實現,使用數組來作為任務池的存放數據結構。在Channel有緩存請求方法和處理請求方法,利用生成者與消費者模式來處理存儲請求,利用反向等待來判斷任務池的非空狀態。

  Channel參與者:

  1. package whut.threadpool; 
  2. //用到了生產者與消費者模式 
  3. //生成線程池,接受客戶端線程的請求,找到一個工作線程分配該客戶端請求 
  4. public class Channel { 
  5.     private static final int MAX_REQUEST = 100;// 并發數目,就是同時可以接受多少個客戶端請求 
  6.     //利用數組來存放請求,每次從數組末尾添加請求,從開頭移除請求來處理 
  7.     private final Request[] requestQueue;// 存儲接受客戶線程的數目 
  8.     private int tail;//下一次存放Request的位置 
  9.     private int head;//下一次獲取Request的位置 
  10.     private int count;// 當前request數量 
  11.     private final WorkerThread[] threadPool;// 存儲線程池中的工作線程 
  12.     // 運用數組來存儲 
  13.     public Channel(int threads) { 
  14.         this.requestQueue = new Request[MAX_REQUEST]; 
  15.         this.head = 0
  16.         this.head = 0
  17.         this.count = 0
  18.         threadPool = new WorkerThread[threads]; 
  19.         // 啟動工作線程 
  20.         for (int i = 0; i < threadPool.length; i++) { 
  21.             threadPool[i] = new WorkerThread("Worker-" + i, this); 
  22.         } 
  23.     } 
  24.     public void startWorkers() { 
  25.         for (int i = 0; i < threadPool.length; i++) { 
  26.             threadPool[i].start(); 
  27.         } 
  28.     } 
  29.     // 接受客戶端請求線程 
  30.     public synchronized void putRequest(Request request) { 
  31.         // 當Request的數量大于或等于同時接受的數目時候,要等待 
  32.         while (count >= requestQueue.length) 
  33.             try { 
  34.                 wait(); 
  35.             } catch (InterruptedException e) { 
  36.             } 
  37.         requestQueue[tail] = request; 
  38.         tail = (tail + 1) % requestQueue.length; 
  39.         count++; 
  40.         notifyAll(); 
  41.     } 
  42.     // 處理客戶端請求線程 
  43.     public synchronized Request takeRequest() { 
  44.         while (count <= 0
  45.             try { 
  46.                 wait(); 
  47.             } catch (InterruptedException e) { 
  48.             } 
  49.         Request request = requestQueue[head]; 
  50.         head = (head + 1) % requestQueue.length; 
  51.         count--; 
  52.         notifyAll(); 
  53.         return request; 
  54.     } 

客戶端請求線程:

  1. package whut.threadpool; 
  2. import java.util.Random; 
  3. //向Channel發送Request請求的 
  4. public class ClientThread extends Thread{ 
  5.     private final Channel channel; 
  6.     private static final Random random=new Random(); 
  7.                                                                 
  8.     public ClientThread(String name,Channel channel) 
  9.     { 
  10.         super(name); 
  11.         this.channel=channel; 
  12.     } 
  13.     public void run() 
  14.     { 
  15.         try
  16.             for(int i=0;true;i++) 
  17.             { 
  18.                 Request request=new Request(getName(),i); 
  19.                 channel.putRequest(request); 
  20.                 Thread.sleep(random.nextInt(1000)); 
  21.             } 
  22.         }catch(InterruptedException e) 
  23.         { 
  24.         } 
  25.     } 

 工作線程:

  1. package whut.threadpool; 
  2. //具體工作線程 
  3. public class WorkerThread extends Thread{ 
  4.                                                        
  5.     private final Channel channel; 
  6.     public WorkerThread(String name,Channel channel) 
  7.     { 
  8.       super(name); 
  9.       this.channel=channel; 
  10.     } 
  11.                                                        
  12.     public void run() 
  13.     { 
  14.         while(true
  15.         { 
  16.             Request request=channel.takeRequest(); 
  17.             request.execute(); 
  18.         } 
  19.     } 
  20.  

#p#

線程池實例2:

  工作線程:

  利用同步塊來處理,利用Vector來存儲客戶端請求。在Channel有緩存請求方法和處理請求方法,利用生成者與消費者模式來處理存儲請求,利用正向等待來判斷任務池的非空狀態。

  這種實例,可以借鑒到網絡ServerSocket處理用戶請求的模式中,有很好的擴展性與實用性。

  利用Vector來存儲,依舊是每次集合的最后一個位置添加請求,從開始位置移除請求來處理。

  Channel參與者:

  1. package whut.threadpool2; 
  2. import java.util.Vector; 
  3. /* 
  4.  * 這個主要的作用如下 
  5.  * 0,緩沖客戶請求線程(利用生產者與消費者模式) 
  6.  * 1,存儲客戶端請求的線程 
  7.  * 2,初始化啟動一定數量的線程 
  8.  * 3,主動來喚醒處于任務池中wait set的一些線程來執行任務 
  9.  */ 
  10. public class Channel { 
  11.     public final static int THREAD_COUNT=4
  12.     public static void main(String[] args) { 
  13.       //定義兩個集合,一個是存放客戶端請求的,利用Vector, 
  14.       //一個是存儲線程的,就是線程池中的線程數目 
  15.                               
  16.       //Vector是線程安全的,它實現了Collection和List 
  17.       //Vector 類可以實現可增長的對象數組。與數組一樣, 
  18.       //它包含可以使用整數索引進行訪問的組件。但Vector 的大小可以根據需要增大或縮小, 
  19.       //以適應創建 Vector 后進行添加或移除項的操作。 
  20.       //Collection中主要包括了list相關的集合以及set相關的集合,Queue相關的集合 
  21.       //注意:Map不是Collection的子類,都是java.util.*下的同級包 
  22.       Vector pool=new Vector(); 
  23.       //工作線程,初始分配一定限額的數目 
  24.       WorkerThread[] workers=new WorkerThread[THREAD_COUNT]; 
  25.                            
  26.       //初始化啟動工作線程 
  27.       for(int i=0;i<workers.length;i++) 
  28.       { 
  29.           workers[i]=new WorkerThread(pool); 
  30.           workers[i].start(); 
  31.       } 
  32.                             
  33.       //接受新的任務,并且將其存儲在Vector中 
  34.       Object task=new Object();//模擬的任務實體類 
  35.       //此處省略具體工作 
  36.       //在網絡編程中,這里就是利用ServerSocket來利用ServerSocket.accept接受一個Socket從而喚醒線程 
  37.                             
  38.       //當有具體的請求達到 
  39.       synchronized(pool) 
  40.       { 
  41.           pool.add(pool.size(), task); 
  42.           pool.notifyAll();//通知所有在pool wait set中等待的線程,喚醒一個線程進行處理 
  43.       } 
  44.       //注意上面這步驟添加任務池請求,以及通知線程,都可以放在工作線程內部實現 
  45.       //只需要定義該方法為static,在方法體用同步塊,且共享的線程池也是static即可 
  46.                             
  47.       //下面這步,可以有可以沒有根據實際情況 
  48.       //取消等待的線程 
  49.       for(int i=0;i<workers.length;i++) 
  50.       { 
  51.           workers[i].interrupt(); 
  52.       } 
  53.     } 

工作線程:

  1. package whut.threadpool2; 
  2. import java.util.List; 
  3. public class WorkerThread extends Thread { 
  4.     private List pool;//任務請求池 
  5.     private static int fileCompressed=0;//所有實例共享的 
  6.                       
  7.     public WorkerThread(List pool) 
  8.     { 
  9.           this.pool=pool;  
  10.     } 
  11.                       
  12.     //利用靜態synchronized來作為整個synchronized類方法,僅能同時一個操作該類的這個方法 
  13.     private static synchronized void incrementFilesCompressed() 
  14.     { 
  15.         fileCompressed++; 
  16.     } 
  17.                       
  18.     public void run() 
  19.     { 
  20.         //保證無限循環等待中 
  21.         while(true
  22.         { 
  23.             //共享互斥來訪問pool變量 
  24.             synchronized(pool) 
  25.             { 
  26.                 //利用多線程設計模式中的 
  27.                 //Guarded Suspension Pattern,警戒條件為pool不為空,否則無限的等待中 
  28.                 while(pool.isEmpty()) 
  29.                 { 
  30.                     try
  31.                         pool.wait();//進入pool的wait set中等待著,釋放了pool的鎖 
  32.                     }catch(InterruptedException e) 
  33.                     { 
  34.                     } 
  35.                 } 
  36.                 //當線程被喚醒,需要重新獲取pool的鎖, 
  37.                 //再次繼續執行synchronized代碼塊中其余的工作 
  38.                 //當不為空的時候,繼續再判斷是否為空,如果不為空,則跳出循環 
  39.                 //必須先從任務池中移除一個任務來執行,統一用從末尾添加,從開始處移除 
  40.                                   
  41.                 pool.remove(0);//獲取任務池中的任務,并且要進行轉換 
  42.             } 
  43.             //下面是線程所要處理的具體工作 
  44.         } 
  45.     } 

原文鏈接:http://dev.yesky.com/433/34834433.shtml

責任編輯:陳四芳 來源: 博客
相關推薦

2023-06-07 13:49:00

多線程編程C#

2011-11-18 10:50:25

設計模式Java線程

2009-03-12 10:52:43

Java線程多線程

2021-11-29 09:38:12

設計模式對象池模式Object Pool

2021-02-06 14:02:55

線程池Builder模式

2013-06-08 13:07:23

Java線程池調度器

2021-09-11 15:26:23

Java多線程線程池

2023-11-22 08:37:40

Java線程池

2020-09-04 10:29:47

Java線程池并發

2009-08-12 13:22:44

Singleton模式

2011-06-13 10:41:17

JAVA

2012-02-01 11:20:23

Java線程

2022-05-26 08:31:41

線程Java線程與進程

2020-08-21 07:23:50

工廠模式設計

2012-05-16 17:22:11

Java設計模式

2012-02-14 12:31:27

Java

2011-11-17 16:03:05

Java工廠模式Clojure

2012-05-16 17:15:04

Java設計模式

2021-06-09 08:53:34

設計模式策略模式工廠模式

2012-02-29 09:41:14

JavaScript
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日韩精品在线免费观看视频 | 国产在线不卡 | 涩涩视频在线播放 | 日韩一级二级片 | 粉嫩av在线| 日批免费看 | 欧美精品久久 | 久久一久久 | 中文字幕国产精品 | 一级黄色片一级黄色片 | 国产精品成人一区二区三区 | 黑人巨大精品欧美一区二区一视频 | 精品一区二区久久久久久久网站 | www.成人久久| 免费观看视频www | 亚洲 欧美 激情 另类 校园 | 国产精品毛片一区二区三区 | 91综合网| 日韩中文字幕区 | 91中文字幕在线观看 | 免费国产精品久久久久久 | 在线观看视频一区 | 亚洲国产日韩欧美 | 国产精品一区一区三区 | 久久影音先锋 | 人人艹人人 | 中文字幕成人免费视频 | 亚洲在线电影 | 午夜成人免费视频 | 99热激情| 日韩亚洲视频在线 | 国产精品99久久久久久宅男 | 国产高清视频在线 | 日韩欧美在线视频观看 | 奇米久久久 | 日韩精品一 | 国产中文一区二区三区 | 欧美视频第三页 | 国产精品久久一区二区三区 | 伊人狠狠干| 免费观看黄色片视频 |