iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 13
1
Software Development

30 天介紹 Java 的 Thread系列 第 13

Day 13 使用 Exchanger 寫 Producer Consumer 程式

  • 分享至 

  • xImage
  •  

延續昨天介紹 Exchanger 的部份,Exchanger 玊要可以將二個 Thread 的資料做交換。在寫Producer Consumer 程式的使用情境,適合使用 Exchanger 這個 Class。Producer 用來產生資料而 Consumer 就是用來消費 Producer 所生產的資料。

以下來撰寫一個 Sample Code, 透過使用 Exchanger Class 來實作 Producer Consumer 的程式:

import java.util.concurrent.Exchanger;

public class ProducerThreadExample implements Runnable {
  private Exchanger<StringBuffer> exchanger;
  private StringBuffer sb = new StringBuffer();

  public ProducerThreadExample(Exchanger<StringBuffer> exchanger) {
    this.exchanger = exchanger;

  }

  @Override
  public void run() {
    try {
      for (int i = 1 ; i <= 10 ; i++) {
        sb.append("message-");
        sb.append(i);
        sb = this.exchanger.exchange(sb);
      }
    } catch(Exception e) {
      throw new RuntimeException(e);
    }
  }
}

上面的程式是 Producer Thread 的程式,主要用來產生 message 字串的訊息,然後放入到 StringBuffer 物件裡,之後會和 Consumer 去做資料的交換,程式如下:

import java.util.concurrent.Exchanger;

public class ConsumerThreadExample implements Runnable {
  private Exchanger<StringBuffer> exchanger;

  public ConsumerThreadExample(Exchanger<StringBuffer> exchanger) {
    this.exchanger = exchanger;
  }

  @Override
  public void run() {
    try {
      for (int i = 1 ; i <= 10 ; i++) {
        StringBuffer sb = new StringBuffer();
        sb = this.exchanger.exchange(sb);
        System.out.println("Consumer:" + sb.toString());
      }

    } catch(Exception e) {
      throw new RuntimeException(e);
    }
  }
}

Consumer Thread 的程式用來和 Producer Thread 交換訊息,Consumer 會傳給 Producer Thread 一個空的 StringBuffer 然後 Producer Thread 會去 append 資料。之後 Consumer Thread 會將交換來的訊息印到 Console 上。主程式啟動 Thread 的程式如下:

import java.util.concurrent.Exchanger;

public class Test {
  public static void main(String args[]) {
    Exchanger<StringBuffer> exchanger = new Exchanger<StringBuffer>();
    ProducerThreadExample p = new ProducerThreadExample(exchanger);
    Thread producerThread = new Thread(p);

    ConsumerThreadExample c = new ConsumerThreadExample(exchanger);
    Thread consumerThread = new Thread(c);

    producerThread.start();
    consumerThread.start();
  }
}

主程式就會用來啟動 Producer Thread 以及 Consumer Thread,執行的結果如下:

Consumer:message-1
Consumer:message-2
Consumer:message-3
Consumer:message-4
Consumer:message-5
Consumer:message-6
Consumer:message-7
Consumer:message-8
Consumer:message-9
Consumer:message-10

使用 Exchanger 寫 Producer Consumer 會有缺點,就是當 Producer Thread產生完資料之後如果呼叫 Exchanger 時就會被阻塞住,要等到 Consumer 也呼叫 Exchanger 才會繼續的往下生產資料執行。因此如果要做 Producer Consumer 的程式,在 Producer 和 Consumer 之間最好要放一個 Queue,這樣 Producer 就可以不管 Consumer 是否有被執行就可以一直生產資料,這樣才有辦法去解 Producer Consumer 程式的耦合,但是要控制好 Queue 不然會有爆掉的機會。


上一篇
Day12 使用 Exchanger Class 來交換 Thread 之間的資料
下一篇
Day 14 介紹 ReentrantLock (一)
系列文
30 天介紹 Java 的 Thread30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言