队列的概念:队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。队列中没有元素时,称为空队列。
用golang实现队列我们需要使用到contain/list这个库。这里提供了push,pop,del的方法。下面我们看一下怎么实现这个队列服务。
list最常用的方式就是新建,新建完了之后是读数据,然后就是到底是从哪个地方开始读,list其实是一个双向链表。下面代码的事例是list的新建以及contain/list库的简单实用:
package main
import (
"container/list"
"fmt"
)
func main() {
l := list.New()
for i := 0; i < 5; i++ {
//这里是从尾部push进去数据
l.PushBack(i)
}
//这里是循环读出list里面的值
for e := l.Front(); e != nil; e = e.Next() {
//这里是读出来
fmt.Print(e.Value)
}
fmt.Println("")
}
好了,contain/list的使用我们介绍完了,下面我们来实现一个简单的队列。用list做队列的思路,首先,一头写,一头读,然后读的时候涉及到删除,另外就是涉及到list的加锁问题,这是用list做队列的整理思路。队列:是先进先出。因为contain/list是并发非安全的,所以我们在使用的过程需要考虑锁的问题。
package main
import (
"container/list"
"fmt"
"sync"
)
func main() {
//实例化队列
q := new(Quque)
q.Push("a")
q.Push("b")
q.Push("c")
fmt.Println(q.Pop()) //打印出a
fmt.Println(q.Pop()) //打印出b
fmt.Println(q.Pop()) //打印出c
}
//这个是queue的数据结构,由于contain/list是线程不安全的,需要加锁处理
type Quque struct {
List list.List
Lock sync.Mutex
}
//入
func (this *Quque) Push(a interface{}) {
defer this.Lock.Unlock()
this.Lock.Lock()
this.List.PushFront(a)
}
//出
func (this *Quque) Pop() interface{} {
defer this.Lock.Unlock()
this.Lock.Lock()
e := this.List.Back()
if e != nil {
this.List.Remove(e)
return e.Value
}
return nil
}
以上这个代码是一个golang本身单独提供队列服务,如果我们是分布提供队列服务的话,那就要再度延伸使用单独的存储服务来实现。以上的主要提供大家学习。