我在想,当多个线程正在读取或写入时,是否有可能拥有无锁队列?我已经看到了一个带有无锁队列的实现,它可以使用一个读取线程和一个写入线程,但对于任何一个都不会超过一个。可能吗?我认为不是。可以/有没有人想证明它?
答案 0 :(得分:14)
有多种算法可用,我最终实现了An Optimistic Approach to Lock-Free FIFO Queues,它通过指针标记避免了ABA问题(需要CMPXCHG8B
上的x86
指令),它运行正常在生产应用程序中(用Delphi编写)。 (Another version, with Java code)
然而,要真正无锁,你还需要一个无锁内存分配器 - 请参阅Scalable Lock-Free Dynamic Memory Allocation(在Concurrent Building Block中实现)或NBMalloc(但到目前为止,我没有使用其中一种)。
的答案答案 1 :(得分:3)
Java的无锁队列实现允许读写。这项工作是通过比较和设置操作(这是一个单CPU指令)完成的。
ConcurrentLinkedQueue
使用一种方法,在这种方法中,线程可以帮助彼此从队列中读取(或轮询)对象。由于它是链接的,队列的头部可以接受写入,而队列的尾部可以接受读取(假设有足够的空间)。所有这些都可以并行完成,完全是线程安全的。
答案 2 :(得分:1)
使用.NET 4.0,有ConcurrentQueue(T) Class 简而言之,根据C#4.0,这是一个无锁实现。另请参阅此blog entry。
答案 3 :(得分:0)
您并不特别需要锁定,而是从队列中删除内容的原子方法。没有锁定和原子test-and-set指令也可以这样做。
答案 4 :(得分:0)
Primoz Gabrijelcic(Delphi Geek)在OmniThreadLibrary中有一个动态锁定免费队列:http://www.thedelphigeek.com/2010/02/omnithreadlibrary-105.html
答案 5 :(得分:0)
使用.NET 4.0,有ConcurrentQueue Class。
https://dotnetfiddle.net/ehLZCm
public static void Main()
{
PopulateQueueParallel(new ConcurrentQueue<string>(), 500);
}
static void PopulateQueueParallel(ConcurrentQueue<string> queue, int queueSize)
{
Parallel.For(0, queueSize, (i) => queue.Enqueue(string.Format("my message {0}", i)));
Parallel.For(0, queueSize,
(i) =>
{
string message;
bool success = queue.TryDequeue(out message);
if (!success)
throw new Exception("Error!");
Console.WriteLine(message);
});
}