使用Golang 实现一个无锁队列

58 min read

下面是一个简单的无锁队列示例,使用Golang实现:

package main

import "sync/atomic"

type node struct {
    value interface{}
    next  *node
}

type LockFreeQueue struct {
    head *node
    tail *node
}

func NewLockFreeQueue() *LockFreeQueue {
    n := &node{}
    return &LockFreeQueue{head: n, tail: n}
}

func (q *LockFreeQueue) Enqueue(value interface{}) {
    n := &node{value: value}

    for {
        tail := q.tail
        next := tail.next
        if tail == q.tail {
            if next == nil {
                if atomic.CompareAndSwapPointer(
                    &tail.next, nil, n) {
                    atomic.CompareAndSwapPointer(&q.tail, tail, n)
                    return
                }
            } else {
                atomic.CompareAndSwapPointer(
                    &q.tail, tail, next)
            }
        }
    }
}

func (q *LockFreeQueue) Dequeue() interface{} {
    for {
        head := q.head
        tail := q.tail
        next := head.next
        if head == q.head {
            if head == tail {
                if next == nil {
                    return nil
                }
                atomic.CompareAndSwapPointer(
                    &q.tail, tail, next)
            } else {
                result := next.value
                if atomic.CompareAndSwapPointer(
                    &q.head, head, next) {
                    return result
                }
            }
        }
    }
}

func main() {
    q := NewLockFreeQueue()
    q.Enqueue(1)
    q.Enqueue(2)
    q.Enqueue(3)
    println(q.Dequeue().(int)) // Output: 1
    println(q.Dequeue().(int)) // Output: 2
    println(q.Dequeue().(int)) // Output: 3
}

这个无锁队列使用了Golang的原子操作,在并发环境下可以实现高效的并发读写操作。同时,这个队列也支持在单线程中进行安全的操作。