美文网首页
第四范式-不使用channel,实现一个线程安全的队列

第四范式-不使用channel,实现一个线程安全的队列

作者: FredricZhu | 来源:发表于2020-08-12 17:20 被阅读0次

main.go主文件

package main

import (
    "fmt"
    "sync"

    "github.com/zhuge20100104/condi_queue/queue"
)

func main() {
    q := queue.New()
    wg := sync.WaitGroup{}

    wg.Add(2)
    go func() {
        defer wg.Done()
        for i := 0; i < 15; i++ {
            q.InQueue(i)
        }
    }()

    go func() {
        defer wg.Done()
        for i := 0; i < 15; i++ {
            ele := q.DeQueue()
            fmt.Println(ele)
        }
    }()
    wg.Wait()
}

queue/queue.go

package queue

import (
    "sync"
)

// Queue 队列对象
type Queue struct {
    values []interface{}
    cond   *sync.Cond
}

// New Queue类的构造函数
func New() *Queue {
    val := make([]interface{}, 0)
    con := sync.NewCond(new(sync.Mutex))
    return &Queue{
        values: val,
        cond:   con,
    }
}

func (q *Queue) lock() sync.Locker {
    return q.cond.L
}

// InQueue 入队操作
func (q *Queue) InQueue(value interface{}) {
    q.lock().Lock()
    defer func() {
        q.lock().Unlock()
    }()
    q.values = append(q.values, value)
    q.cond.Signal()
    q.cond.Broadcast()

}

// IsEmpty 判断队列是否为空
func (q *Queue) IsEmpty() bool {
    q.lock().Lock()
    defer q.lock().Unlock()
    q.cond.Signal()
    q.cond.Broadcast()
    return len(q.values) == 0
}

// DeQueue 出队操作
func (q *Queue) DeQueue() interface{} {
    q.lock().Lock()
    if len(q.values) == 0 {
        q.cond.Wait()
    }
    defer q.lock().Unlock()
    value := q.values[0]
    q.values = q.values[1:]
    q.cond.Signal()
    q.cond.Broadcast()
    return value
}

程序输出


图片.png

相关文章

网友评论

      本文标题:第四范式-不使用channel,实现一个线程安全的队列

      本文链接:https://www.haomeiwen.com/subject/bdapdktx.html