企业电子化的专家 Ragic 教你如何利用各种软件、
云服务让公司快速升级!
加入 Ragic 企业电子化的行列!
云工作术
各类应用演示
案例故事
逃离恶梦
关于 Ragic
云数据库
博客
关于Ragic
云工作术
各类应用演示
案例故事
逃离恶梦
关于 Ragic
云工作提案
软件比较
表格技巧
数码新鲜事
3C小学堂
免费范本
产业应用
理财
健康
职场 / 生活
制造业
零售业
服务业与其他产业
工程地产
政府 NGO
职涯与合作伙伴故事
电子化迷思破解
逃离 Excel 灾难
告别 ERP 恶梦
打印件恐怖故事
职场日记
我们的故事
Ragic教学
社群与客服
公告

Blocking Queue异步处理 – 快速响应运行较花时间的工作

作者:Jeff Kuo

常常在系统里面都会有一些工作运行起来特别花时间,比如说寄送电邮,或是写入复杂数据到数据库中等等。在一般系统中如果没有特殊处理的话,会造成用户在使用的时候感觉很慢才有响应,而响应其实只是一个简单的运行完成的确认。

这时候异步处理这个好用的技巧就派上用场了,如果我们 能够让用户运行这个动作的时候,不用真的等到他完成再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楼
    用户条款 | 隐私权政策