Skip to content

Latest commit

 

History

History
94 lines (78 loc) · 1.92 KB

86fc324b72a60c96fe24c8e160c8a838.md

File metadata and controls

94 lines (78 loc) · 1.92 KB

协程安全队列

使用Golang的channel实现一个并发安全的队列,支持阻塞和非阻塞,实现入队和出队方法。

package queue

import "errors"

type BlockQueue struct {
    data        chan interface{}
    cap         int
    timeout     int
}

func NewBlockQueue(cap, timeout int) *BlockQueue {
    if cap <= 0 {
        return nil
    }
    queue := new(BlockQueue)
    queue.data = make(chan interface{}, cap)
    queue.cap = cap
    queue.timeout = timeout
    return queue
}

func (bq *BlockQueue) Len() int {
    return len(bq.data)
}

func (bq *BlockQueue) Cap() int {
    return bq.cap
}

func (bq *BlockQueue) Enqueue(val interface{}) error {
    select {
        case bq.data <- val:
            return nil
        case time.After(time.Duration(bq.timeout) * time.Second):
            return errors.New("Enqueue timeout.")
    }
}

func (bq *BlockQueue) Dequeue() (interface{}, error) {
    select {
        case data := <- bq.data
            return data, nil
        case time.After(time.Duration(bq.timeout) * time.Second):
            return nil, errors.New("Dequeue timeout.")
    }
}

type NonBlockQueue struct {
    data        chan interface{}
    cap         int
}

func NewNonBlockQueue(cap int) *NonBlockQueue {
    if cap <= 0 {
        return nil
    }
    queue := new(NonBlockQueue)
    queue.data = make(chan interface{}, cap)
    queue.cap = cap
    return queue
}

func (nq *NonBlockQueue) Len() int {
    return len(nq.data)
}

func (nq *NonBlockQueue) Cap() int {
    return nq.cap
}

func (nq *NonBlockQueue) Enqueue(val interface{}) error {
    select {
        case nq.data <- val:
            return nil
        default:
            return errors.New("Queue is full.")
    }
}

func (nq *NonBlockQueue) Dequeue() (interface{}, error) {
    select {
        case data := <- nq.data
            return data, nil
        default:
            return nil, errors.New("Queue is empty.")
    }
}