1

根据这篇文章,我正在尝试在 Java 中扩展无锁队列的实现。

对于我的实现,我仅限于使用原子变量/引用。另外是我的队列应该有一个最大大小。因此,当队列已满时,putObject() 应该阻塞,如果队列为空,则 getObject() 应该阻塞。

目前我不知道如何在不使用锁的情况下解决这个问题。

例如,当使用 AtomicInteger 时,修改操作将是原子的。但是仍然存在我必须在 putObject() 和 getObject() 中处理检查和修改情况的问题,对吗?所以仍然存在检查当前队列大小后会中断入队线程的情况。

我目前的问题是,这个问题是否可以根据我目前的限制解决?

问候

4

2 回答 2

1

如果您有一个可行的、正常工作的无锁队列,那么添加最大大小就像添加一个 AtomicInteger 并在正确的时间进行检查、inc、dec 一样简单。

添加元素时,您基本上会预先保留队列中的位置。就像是:

while (true) {
    int curr = count.get();
    if (curr < MAX) {
        if (count.compareAndSet(curr, curr + 1)) {
            break;
        }
    }
    else {
        return FULL;
    }
}

然后添加新元素并将其链接。获取时,您可以像往常一样访问头部并检查是否有任何东西要从队列中返回。如果是,则返回它,然后减少计数器。如果没有,您只需返回 EMPTY。请注意,我没有使用计数器来检查队列是否真的为空,因为计数器可能为 1,而由于预保留方法,队列中还没有任何链接。所以我只是相信你的队列有办法告诉你“我有什么东西”或没有(它必须,否则 get() 永远不会工作)。

于 2013-12-20T20:18:31.033 回答
0

这是一个非常常见的问题,通常通过使用环形缓冲区来解决。这就是网络适配器和Disruptor库一样使用的东西。我建议你看看 Disruptor 和一个很好的例子,说明你可以用环形缓冲区做什么。

于 2013-12-20T11:13:34.837 回答