队列类型-基本使用

基本使用

package main

import (
    "fmt"
    "time"
    "github.com/gogf/gf/v2/os/gtimer"
    "github.com/gogf/gf/v2/container/gqueue"
)

func main() {
    q := gqueue.New()

    // 数据生产者,每隔1秒往队列写数据
    gtimer.SetInterval(time.Second, func() {
        v := gtime.Now().String()
        q.Push(v)
        fmt.Println("Push:", v)
    })

    // 3秒后关闭队列
    gtimer.SetTimeout(3*time.Second, func() {
        q.Close()
    })

    // 消费者,不停读取队列数据并输出到终端
    // 如果队列中没有数据,则会阻塞
    // 可以结合select语法进行使用
    // 例子
    // for {
    //     select {
    //         case v := <-queue.C:
    //             if v != nil {
    //                 fmt.Println(v)
    //             } else {
    //                 return
    //             }
    //         }
    // }
    for {
        if v := q.Pop(); v != nil {
            fmt.Println(" Pop:", v)
        } else {
            break
        }
    }

    // 第3秒时关闭队列,这时程序立即退出,因此结果中只会打印2秒的数据。 执行后,输出结果为:
    // Output:
    // Push: 2021-09-07 14:03:00
    //  Pop: 2021-09-07 14:03:00
    // Push: 2021-09-07 14:03:01
    //  Pop: 2021-09-07 14:03:01
}

元素入队/出队

package main

import (
    "fmt"
    "time"
    "github.com/gogf/gf/v2/os/gtimer"
    "github.com/gogf/gf/v2/container/gqueue"
)

func main() {
    q := gqueue.New()

    for i := 0; i < 10; i++ {
        q.Push(i)
    }

    fmt.Println(q.Pop())
    fmt.Println(q.Pop())
    fmt.Println(q.Pop())

    // Output:
    // 0
    // 1
    // 2
}

队列长度

package main

import (
    "fmt"
    "time"
    "github.com/gogf/gf/v2/os/gtimer"
    "github.com/gogf/gf/v2/container/gqueue"
)

func main() {
    q := gqueue.New()

    q.Push(1)
    q.Push(2)

    fmt.Println(q.Len())
    // size是len方法的别称
    fmt.Println(q.Size())

    // May Output:
    // 2
    // 2
}

队列关闭

package main

import (
    "fmt"
    "time"
    "github.com/gogf/gf/v2/os/gtimer"
    "github.com/gogf/gf/v2/container/gqueue"
)

func main() {
    q := gqueue.New()

    for i := 0; i < 10; i++ {
        q.Push(i)
    }

    fmt.Println(q.Pop())
    q.Close()
    fmt.Println(q.Pop())
    fmt.Println(q.Len())

    // Output:
    // 0
    // <nil>
    // 0
}

gqueue与glist

gqueue的底层基于glist链表实现动态大小特性,在队列满或者在队列空时读取数据会产生阻塞。

glist是一个并发安全的链表,并可以允许在关闭并发安全特性的时和一个普通的list链表无异,在存储和读取数据时不会发生阻塞。