go 无锁队列

jinjiashan · · 4270 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

无锁队列适用场景:

     两个线程之间的交互数据, 一个线程生产数据, 另外一个线程消费数据,效率高

缺点:需要使用固定分配的空间,不能动态增加/减少长度,存在空间浪费和无法扩展空间问题

 

package main

import (
       "fmt"
       "reflect"
       "strings"
       "time"
)
type LoopQueue struct{
       start  int
       end    int
       length int
       name   string
       data   []interface{}
}

func (this* LoopQueue)InitQueue(length int, name string)bool{
       if nil == this || length <= 0{
              return false
       }
       this.data = make([]interface{}, length)
       this.length = length
       this.name = name
       this.start = 0
       this.end = 0
       return true
}



func (this* LoopQueue)Push(data interface{})bool{
       if nil == this{
              panic("LoopQueue is nil")
       }
       if this.isFull(){
              return false
       }
       var end int = this.getEnd()
       this.data[end] = data
       this.end = (end+1)%this.length
       return true
}

func (this* LoopQueue)Pop() (bool, interface{}) {
       if nil == this{
              panic("LoopQueue is nil")
       }
       if this.isEmpty(){
              return  false, nil
       }
       var start = this.getStart()
       var startValue interface{} = this.data[start]
       this.start = (start+1) % this.length
       return true, startValue
}

func (this* LoopQueue)isEmpty()bool{
       if nil == this{
              panic("LoopQueue is nil")
       }
       if this.getStart() == this.getEnd(){
              return true
       }
       return false
}

func (this* LoopQueue)isFull()bool{
       if nil == this{
              panic("LoopQueue is nil")
       }
       if this.getEnd() +1 == this.getStart(){
              return true
       }
       return false
}

func (this* LoopQueue)getStart()int{
       return this.start % this.length
}

func (this* LoopQueue)getEnd()int{
       return this.end % this.length
}


var Q LoopQueue
func Create(){
       var index int = 0
       for{
              ret := Q.Push(index)
              if ret{
                     fmt.Println("PushOk", "index=", index)
                     index++
              }else{
                     fmt.Println("PushError", "index=", index)
              }
              time.Sleep(1e9)
       }
}

func Consum(){
       for{
              ret, data := Q.Pop()
              if ret{
                     fmt.Println("PopSucc", "data=",data)
              }else{
                     fmt.Println("PopError")
              }
              time.Sleep(1e9)
       }
}
//实现环形队列
func main(){
       Q.InitQueue(10, "test")
       go Create()
       go Consum()
       for{
              time.Sleep(1e9)
       }
}

有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

4270 次点击  
加入收藏 微博
3 回复  |  直到 2020-11-16 17:34:41
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传