2014-02-26 41 views
3

有了Java客户端,我该如何使用couchbase来实现FIFO队列,线程安全吗?可以有许多线程从队列中弹出,并推入队列。队列中的每个对象都是一个字符串[]。如何使用couchbase作为FIFO队列

回答

4

Couchbase没有任何用于创建队列的内置功能,但您可以自己做。

我会在下面的简短例子中解释如何做到这一点。 也就是说我们有名为queue的队列,它将有名称为item:<index>的项目。要实现队列,您需要使用以下键值存储值:<queue_name>:item:<index>,其中索引将是单独的键queue:index,您需要在推送到队列时递增,并在弹出时递减。

在couchbase中,您可以使用递增和递减操作来实现队列,因为那些操作是原子和线程安全的。

所以你的push和pop函数的代码会像:

void push(string queue, string[] value){ 
    int index = couchbase.increment(queue + ':index'); 
    couchbase.set(queue + ':item:' + index, value); 
} 
string[] pop(string queue){ 
    int index = couchbase.get(queue + ':index'); 
    string[] result = couchbase.get(queue + ':item:' + index); 
    couchbase.decrement(queue + ':index'); 
    return result; 
} 

对不起代码,我已经使用Java和couchbase Java客户端在很久以前。如果现在Java客户端具有回调,如nodejs客户端,则可以重写该代码以使用回调。我想,这会更好。

此外,您可以添加额外支票到设置操作 - 使用add(在C#客户端它称为StoreMode.Add)操作将抛出异常,如果具有给定键的项目已经存在。您可以捕获该异常并再次为相同的参数调用push函数。

UPD:对不起,早上太早,所以我想不清楚。 对于fifo,@avsej说你需要两个计数器:queue:headqueue:tail。因此,对于FIFO:

void push(string queue, string[] value){ 
    int index = couchbase.increment(queue + ':tail'); 
    couchbase.set(queue + ':item:' + index, value); 
} 
string[] pop(string queue){ 
    int index = couchbase.increment(queue + ':head') - 1; 
    string[] result = couchbase.get(queue + ':item:' + index); 
    return result; 
} 

注:代码会略有不同取决于queue:tailqueue:head起始值(这将是零个或一个或别的东西)。

此外,您可以设置一些max价值的计数器,达到它后,queue:tailqueue:head将被重置为0(仅限于文件数量)。如果你真的需要这个,你也可以为每个文档设置expire值。

+0

你的代码示例显示了堆栈,但是相同的想法可以应用于fifo,除了它需要两个索引,比如'queue +':head''和'queue +':tail''和on推它会增加尾巴,在弹出它应该减少头 – avsej

+0

@ m03geek这将弹出最后插入的对象每一次? [@] avsej但头要使用什么值? – twb

+0

@twb是的,它会弹出最后一个对象。 – m03geek