go 无锁队列

无锁队列适用场景:

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

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

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)
       }
}

本文分享自微信公众号 - Golang语言社区(Golangweb)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2017-07-09

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 【JS游戏编程基础】关于js里的this关键字的理解

    this关键字在c++,java中都提供了这个关键字,在刚开始学习时觉得有难度,但是只要理解了,用起来就方便多了,下面通过本篇文章给大家详解js里this关键字...

    李海彬
  • 社区开源框架网络模块:ConnectionManager详解

    地址:https://github.com/Golangltd/LollipopCreator

    李海彬
  • Oculus + Node.js + Three.js 打造VR世界

    Oculus Rift 是一款为电子游戏设计的头戴式显示器。这是一款虚拟现实设备。这款设备很可能改变未来人们游戏的方式。 周五Hackday Showcase的...

    李海彬
  • Promise的简单实现

    本篇文章通过构建一个简单的Promise对象来了解如何做到异步获得数据。 使用方法 const fetch = function(url) { return...

    IMWeb前端团队
  • Button按钮--inject与provide

    inject 和 provider 是vue中的组合选项,需要一起使用。目的是允许一个祖先组件向其所有子孙后代注入依赖(简单地说就是祖先组件向子孙后代传值的一种...

    用户1148399
  • 再也不用被this苦恼了

    前端编程对于this再熟悉不过了,今日来个老调重弹温故知新,肯定有很多大佬已经完全吃透了this原理,敬请出门左拐。对于理解this似懂非懂的同学可以借鉴一波

    Jack Chen
  • PHP code 验证码生成类定义和简单使用示例

    本文实例讲述了PHP code 验证码生成类定义和简单使用。分享给大家供大家参考,具体如下:

    砸漏
  • springboot @EnableScheduling 启用多线程

    使用@EnableScheduling注解后,可以发现所有任务都排队执行,并且调度器线程名称都是“taskScheduler-1”

    路过君
  • Promise的简单实现

    这个fetch()的方法返回了一个Promise对象,接着我们就可以用then来对获得的数据进行处理,catch来捕获可能的错误。

    IMWeb前端团队
  • 从零开始学 Web 之 JavaScript 高级(一)原型,贪吃蛇案例

    由来:构造函数的问题。如果一个构造函数中有一个匿名方法,那么每实例化一个对象,然后在对象调用这个方法的时候,由于每个对象的方法都是各自的,所以每次调用这个方法的...

    Daotin

扫码关注云+社区

领取腾讯云代金券