Ragic 部落格
企業電子化的專家 Ragic 教你如何利用各種軟體、
雲端服務讓公司快速升級!
加入 Ragic 企業電子化的行列!
雲端工作術
各類應用示範
案例故事
逃離惡夢
關於 Ragic
Facebook Twitter YouTube
雲端資料庫
部落格
關於Ragic
雲端工作術
各類應用示範
案例故事
逃離惡夢
關於 Ragic

Blocking Queue非同步處理 – 快速回應執行較花時間的工作

作者:Jeff Kuo

常常在系統裡面都會有一些工作執行起來特別花時間,比如說寄送e-mail,或是寫入複雜資料到資料庫中等等。在一般系統中如果沒有特殊處理的話,會造成使用者在使用的時候感覺很慢才有回應,而回應其實只是一個簡單的執行完成的確認。

這時候非同步處理這個好用的技巧就派上用場了,如果我們 能夠讓使用者執行這個動作的時候,不用真的等到他完成再return回去給使用者,其實只要被呼叫的程式確認已經收到了指令跟參數,就可以回應了,而實際 上執行工作的任務就交給另一個thread來處理即可。

要怎麼做到這點呢?筆者過去看過了不少有趣的解決方式,常看到一些資料庫的愛用者的作法,就是開一個table,然後把一筆一筆要執行的指令內容塞到這個table,然後由另一個thread來定期掃這個table未執行過的指令, 找到還沒執行的指令就把他執行。這也是一種解決方式啦,只是感覺為了執行指令還要維護一個table麻煩了點,而隨時去掃瞄table效能也差了一點。

比較聰明一點的開發者就會想了,那我們在記憶體裡面作一個queue來記錄包成物件的要執行的指令就好啦,就不必寫在資料庫裡面。但是執行方式也是一樣,我們開一個thread每一定時間執行一次來掃這個queue執行還沒執行過的工作。這樣效能是不差,但是還是沒辦法達到趨近於及時的效果,也就是說至少都還是得等一定時間系統才會來執行這樣的工作。

其實有一個更簡單的解法,這樣的queue通常根本不必自己寫,有一種東西叫做 Blocking Queue,也就是說他是一個會把thread lock住的一個queue,什麼時候會lock住呢?就是在這個queue東西被清光的時候。

也就是說,這個queue的使用方式很簡單,我們要執行的工作包成物件跟之前一樣就把他丟到這個Blocking Queue裡面,而另外我們起一個thread在一個迴圈裡面不斷的從Blocking Queue中取得下一個要執行的工作,如果queue裡面已經沒有工作可以給這個thread作了,這個thread就會被queue停住,直到有下一個工作丟入queue中,才會把thread叫醒,繼續執行工作。Java文件中有的簡單用法大概如下:

class Producer implements Runnable {

private final BlockingQueue queue;

Producer(BlockingQueue q) { queue = q; }

public void run() {

try {

while(true) { queue.put(produce()); }

} catch (InterruptedException ex) { ... handle ...}

}

Object produce() { ... }

}

class Consumer implements Runnable {

private final BlockingQueue queue;

Consumer(BlockingQueue q) { queue = q; }

public void run() {

try {

while(true) { consume(queue.take()); }

} catch (InterruptedException ex) { ... handle ...}

}

void consume(Object x) { ... }

}

class Setup {

void main() {

BlockingQueue q = new SomeQueueImplementation();

Producer p = new Producer(q);

Consumer c1 = new Consumer(q);

Consumer c2 = new Consumer(q);

new Thread(p).start();

new Thread(c1).start();

new Thread(c2).start();

}

}

這樣的blocking queue其實自己實做起來還算滿簡單的,筆者當初想到這種解法的時候便自己implement了一個Blocking Queue來達到這樣目的,不過一陣子後就發現Java 1.5以後,standard library裡面就給了一個Blocking Queue來給你使用。就更省事更不會出錯啦!

部落格背後使用 Ragic! : 最強大的 No Code 企業電子化工具
把資料放在Excel上不只是拖累團隊的行政效率,他也很容易出錯並且無法進行任何內控。
當您的團隊成長時,使用Excel管理資料就會越來越痛苦。
建立你們的第一個雲端資料庫!

馬上註冊
免費試用 Ragic!

用 Google 帳號註冊

立即科技 Ragic, Inc.
02-7728-8692
台北市中正區南昌路二段81號9樓