Pattern 參與者 :
* Data 參予者 :
* Producer 參予者 :
* Consumer 參予者 :
* Channel 參予者 :
示意圖 :
使用範例 :
* Main 類 :
Main 類會建立 Table, MakerThread 與 EaterThread 物件並啟動它們. 代碼如下 :
- package dp.thread.ch5;
- public class Main {
- public static void main(String args[]){
- Table table = new Table(3); //建立可以放 3 個蛋糕的桌子
- new MakerThread("MakerThread-1", table, 123231,5).start();
- new MakerThread("MakerThread-2", table, 456654,5).start();
- new MakerThread("MakerThread-3", table, 789987,5).start();
- new EaterThread("EaterThread-1", table, 123321,5).start();
- new EaterThread("EaterThread-2", table, 456654,5).start();
- new EaterThread("EaterThread-3", table, 789987,5).start();
- }
- }
MakerThread 類是用來製作蛋糕並放在桌上的類, 也就是廚師. 代碼如下 :
- package dp.thread.ch5;
- public class Main {
- public static void main(String args[]){
- Table table = new Table(3); //建立可以放 3 個蛋糕的桌子
- new MakerThread("MakerThread-1", table, 123231,5).start();
- new MakerThread("MakerThread-2", table, 456654,5).start();
- new MakerThread("MakerThread-3", table, 789987,5).start();
- new EaterThread("EaterThread-1", table, 123321,5).start();
- new EaterThread("EaterThread-2", table, 456654,5).start();
- new EaterThread("EaterThread-3", table, 789987,5).start();
- }
- }
EaterThread 類用來表示從桌上拿蛋糕來吃的客人. 桌上的蛋糕可以使用 Table 類的 take 方法獲取. 接者 MakerThread 會隨機暫停模擬 "吃蛋糕所花費的時間". 代碼如下 :
- package dp.thread.ch5;
- import java.util.*;
- public class EaterThread extends Thread{
- private final Random random;
- private final Table table;
- private int taskCount = 10;
- public EaterThread(String name, Table t, long seed, int tc){
- super(name);
- this.table = t;
- this.random = new Random(seed);
- if(tc>0){
- taskCount = tc;
- }
- }
- public void run(){
- try{
- for(int i=0;i
- String cake = table.take();
- //System.out.println("Cake:"+cake+" is taken by "+getName());
- Thread.sleep(random.nextInt(1500));
- }
- }catch(InterruptedException e){
- e.printStackTrace();
- }
- }
- }
Table 類代表用來放置蛋糕的桌子. 蛋糕可以放的數目由該建構子傳入參數決定. 代碼如下 :
- package dp.thread.ch5;
- public class Table {
- private final String[] buffer;
- private int tail; //下一個put 的位址
- private int head; //下一個take 的地方
- private int count; //buffer 內的蛋糕數
- public Table(int count){
- this.buffer = new String[count];
- this.head = 0;
- this.tail = 0;
- this.count = 0;
- }
- public synchronized void put(String c) throws InterruptedException{
- System.out.println(Thread.currentThread().getName()+ " puts "+c);
- while(count >= buffer.length){
- wait();
- }
- buffer[tail] = c;
- tail = (tail + 1) % buffer.length;
- count++;
- notifyAll();
- }
- public synchronized String take() throws InterruptedException{
- while(count <= 0){
- wait();
- }
- String cake = buffer[head];
- head = ( head+1 ) % buffer.length;
- count--;
- notifyAll();
- System.out.println(Thread.currentThread().getName()+ " takes "+cake);
- return cake;
- }
- }
補充說明 :
@. 在Table 類中的 put 方法中使用了 Guarded Suspension Pattern. 而警戒條件則是 while 條件的邏輯判斷, 如下所示 :
- while(count >= buffer.length){ //若蛋糕數大於等於, Table 所能放的數目則暫停線程.
- wait();
- }
- while(count <= 0){ //若桌上已沒有蛋糕, 則暫停線程
- wait();
- }
沒有留言:
張貼留言