github.com/code-reading/golang@v0.0.0-20220303082512-ba5bc0e589a3/coding/container/03-list-safety.go (about)

     1  package main
     2  
     3  import (
     4  	"container/list"
     5  	"fmt"
     6  	"sync"
     7  )
     8  
     9  type Queue struct {
    10  	list.List
    11  	sync.Mutex
    12  }
    13  
    14  func NewQueue() *Queue {
    15  	return &Queue{}
    16  }
    17  
    18  func (p *Queue) Push(v interface{}) {
    19  	p.Lock()
    20  	defer p.Unlock()
    21  	p.PushFront(v)
    22  }
    23  
    24  func (p *Queue) Pop() (v interface{}) {
    25  	p.Lock()
    26  	defer p.Unlock()
    27  	iter := p.Back()
    28  	if iter != nil {
    29  		v = iter.Value
    30  	}
    31  	p.Remove(iter)
    32  	return v
    33  }
    34  
    35  func (p *Queue) Dump() {
    36  	for e := p.Front(); e != nil; e = e.Next() {
    37  		fmt.Printf("%v ", e.Value)
    38  	}
    39  }
    40  
    41  func main() {
    42  	q := NewQueue()
    43  	wg := &sync.WaitGroup{}
    44  	wg.Add(2)
    45  	go func() {
    46  		defer wg.Done()
    47  		for i := 0; i < 3; i++ {
    48  			q.Push(i)
    49  		}
    50  	}()
    51  	go func() {
    52  		defer wg.Done()
    53  		for i := 0; i < 10; i += 3 {
    54  			q.Push(i)
    55  		}
    56  	}()
    57  	q.Push(10)
    58  	wg.Wait()
    59  	fmt.Println("pop :", q.Pop())
    60  	q.Dump()
    61  
    62  }
    63  
    64  // pop : 10
    65  // 2 1 0 9 6 3 0