iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 30
2
Software Development

30 天介紹 Java 的 Thread系列 第 30

Day 30 介紹 Thread Per Message 模式

Thread Per Message 模式是指每一個 Message 會給一個 Thread 去處理,就像是射後不理只要把工作分配給其它執行緒去處理之後就不會去管,這樣呼叫端就可以處理其它的工作。通常適合使用的情境在於如果 Client 端呼叫 Server 端時,當 Server 端接收到 Request 時,會去另外啟動一個執行緒去處理 Request 的工作。這樣 Server 端就可以另外的去做其它的工作,例如等待其它 Client 端的 Request。

以下寫一個 Thread Per Message 的 Sample Code 如下:

import java.util.concurrent.ExecutorService;

public class Host {
  public void request(ExecutorService es, String clientID, String message) {
     es.execute(new RequestThread(clientID, message));
  }
}

Host 類別主要是,如果收到 Client 的 Request 訊息時就會執行 RequestThread 的執行緒程式,以下是 RequestThread 執行緒程式的 Sample Code:

public class RequestThread implements Runnable {
  private String clientID;
  private String message;

  public RequestThread(String clientID, String message) {
    this.clientID = clientID;
    this.message = message;
  }
  @Override
  public void run() {
     String currentThreadName = Thread.currentThread().getName();
     System.out.println("Thread Name:" + currentThreadName + " Client ID:" + this.clientID + " message:" + this.message);
  }
}

當執行到執行緒程式時會將目前的執行緒名稱、Client 傳進來的 ID 和 message 訊息,輸出到 Console 上,以下是主程式 Client 端的呼叫部份:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Test {
  public static void main(String args[]) {
    ExecutorService es = Executors.newFixedThreadPool(5);
    try {
      Host host = new Host();
      for (int i = 1; i <= 5; i++) {
        host.request(es, "client" + i, "message" + i);
      }
    } catch(Exception e) {
      throw new RuntimeException(e);
    } finally {
       es.shutdown();
    }

  }
}

在主程式裡面會使用 ExectorService 來管理執行緒的 Pool,然後會使用 5 次的迴圈來模擬 Client 端的 request 呼叫,當主程式執行完畢之後就會呼叫 ExecutorService 的 shutdown 方法關閉,以下是執行的結果:

Thread Name:pool-1-thread-1 Client ID:client1 message:message1
Thread Name:pool-1-thread-2 Client ID:client2 message:message2
Thread Name:pool-1-thread-3 Client ID:client3 message:message3
Thread Name:pool-1-thread-4 Client ID:client4 message:message4
Thread Name:pool-1-thread-5 Client ID:client5 message:message5

從執行的結果裡可以看到每一個 client 端的呼叫 ID 都會對應到不同的 Thread 名稱,也就是說每個 message 都會由不同的執行緒來處理。因此在這裡為了怕執行緒無限的打開,所以使用 ExecutorService 的 pool 來管理執行緒的數量。

最後的總結是終於完成了 30 天的鐵人賽,在這個過程中主要會先決定好這 30 天要寫的所有標題,然後再去看書或是網站來學習一些不懂的東西,之後在去撰寫程式來確認執行的結果和理解的是否有一樣,最後才進行寫文章的動作。在這個過程中雖然有點累,但是看到完賽和學習到一些之前不懂的技術,就會感到有成就感。

感謝~~~~~~~


上一篇
Day 29 介紹 Worker Thread 模式
系列文
30 天介紹 Java 的 Thread30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 則留言

1
Darwin Watterson
iT邦好手 1 級 ‧ 2018-11-13 09:09:49

恭喜完賽!/images/emoticon/emoticon64.gif

一般來說,就是因為執行緒的開發有一定的維護風險,才會造就
Quartz、Hibernate、Spring全家餐... 這些成熟框架套件的崛起!

另外,明年龜甲文對於Java的新政策不知道會不會又趕跑一些開發者!
(從今年鐵人賽主題就看出 Python 的崛起!)
不過我是相信
『Spring服務不止,Java不死!』/images/emoticon/emoticon12.gif

Thank you!

有了 Framework 在使用上,變的比較方便。像是 Spring 我也是很喜歡使用,覺得設計的還不錯。

看了這個留言讓我也想來學習 Python 了。

我私心是選 Scala! XD

哈哈,我也有在用 Scala。有些用 Java 寫要好幾行的 code,Scala 一行就夠了

0
sam871026
iT邦新手 4 級 ‧ 2024-01-12 08:28:43

感謝分享,5年後才來看還是收穫許多~

我要留言

立即登入留言