企業電子化的專家 Ragic 教你如何利用各種軟體、
雲端服務讓公司快速升級!
加入 Ragic 企業電子化的行列!
雲端工作術
各類應用示範
案例故事
逃離惡夢
關於 Ragic
雲端資料庫
部落格
關於Ragic
雲端工作術
各類應用示範
案例故事
逃離惡夢
關於 Ragic
雲端工作提案
表格技巧
數位新鮮事
3C小學堂
免費範本
產業應用
理財
健康
職場 / 生活
製造業
服務業
農林漁牧
工程地產
政府 NGO
Ragic 職涯故事
逃離 Excel 災難
告別 ERP 惡夢
電子化迷思破解
我們的故事
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
    info@ragic.com
    台北市中正區南昌路二段81號9樓
    使用者條款 | 隱私權政策