golang中的队列
2018年8月24日
golang中自带list,但自带的是并发不安全的,如果使用,必须还得自己封装!
这里说两种方式,一种是利用channel,一种是自带list+sync
channel 的方式实现比较简单,效率也比较高,缺点就是只能自定义长度的队列(简单使用,可以,非常方便)。
主要是利用channel的缓冲和阻塞实现:
1 2 3 4 5 6 7 8 |
ch = make(chan int,1000) func addList() { for i:=0;i<10000;i++ { ch<-i } } go addList() |
添加队列啦;使用的时候直接
<-ch
这里的ch是全局的,一共放了10000,这个地方有优化空间,就是ch为1000的缓存,在使用了还剩下100的时候就要填充队列,这里可以自己优化,这里只是告诉一个简单的示例告诉你,channel可以用作队列,在简单使用的时候
下边看下list的封装可以并发的队列:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
package tools import ( "container/list" "fmt" "sync" ) type Queue struct { data *list.List lock *sync.Mutex } func NewQueue() *Queue { q := new(Queue) q.data = list.New() q.lock = new(sync.Mutex) return q } func (q *Queue) Push(v interface{}) { defer q.lock.Unlock() q.lock.Lock() q.data.PushFront(v) } func (q *Queue) Pop() interface{} { defer q.lock.Unlock() q.lock.Lock() if q.data.Len() == 0 { return nil } iter := q.data.Back() v := iter.Value q.data.Remove(iter) return v } func (q *Queue) Dump() { for iter := q.data.Back(); iter != nil; iter = iter.Prev() { fmt.Println("item:", iter.Value) } } |
这里就是利用锁的机制,防止在并发的时候出先并发错误!