zoukankan      html  css  js  c++  java
  • golang slice的判空 和 并发安全

    如何判断slice是否为空

    判断slice是否为空,不能与nil进行比较做判断,因为slice有可能已初始化。而是应该使用len计算长度。

    例如

    package main
    
    import (
        "fmt"
    )
    
    func main() {
        var slice1 []int
        slice2 := []int{}
        
        fmt.Println("slice1 == nil:", slice1 == nil)
        fmt.Println("slice1 len:", len(slice1))
        
        fmt.Println("slice2 == nil:", slice2 == nil)
        fmt.Println("slice2 len:", len(slice2))
    }
    
    

    output:

    slice1 == nil: true
    slice1 len: 0
    slice2 == nil: false
    slice2 len: 0

    slice的并发读写

    slice不是并发安全的。

    看下面的例子,在并发append数据过程中,数据会有丢失。

    package main
    
    import (
        "fmt"
        "time"
    )
    
    var slice1 []int
    
    
    func appendValue(i int) {
        slice1 = append(slice1, i)
    }
    
    func main(){
        
        
        for i := 0; i<10000; i++ {
            go appendValue(i)
        }
        
        time.Sleep(time.Second)
        
        for i, v := range slice1 {
            fmt.Println(i,v)
        }
    }
    

    output:

    ...
    7516 9996
    7517 9995
    7518 9997
    7519 9998
    7520 9999

    从输出可以看到,slice不是并发安全的,数据有丢失。

    如何达到并发安全?

    加锁是一种方式。

    看下面的例子,通过加锁,达到互斥效果,实现并发安全。

    package main
    
    import (
        "fmt"
        "sync"
        "time"
    )
    
    var slice1 []int
    
    var lock sync.Mutex
    
    
    func appendValue(i int) {
        lock.Lock()
        defer lock.Unlock()
        
        slice1 = append(slice1, i)
    }
    
    func main(){
        
        
        for i := 0; i<10000; i++ {
            go appendValue(i)
        }
        
        time.Sleep(time.Second)
        
        for i, v := range slice1 {
            fmt.Println(i,v)
        }
    }
    

    output:

    9991 9627
    9992 9991
    9993 9995
    9994 9993
    9995 9992
    9996 9998
    9997 9278
    9998 9948
    9999 9999

    从输出可以看到,数据没有丢失,可以正常打印。

    Just try, don't shy.
  • 相关阅读:
    DBMS_SCHEDULER 的使用
    Android 鲜为人知的 8 个小秘密
    你正在使用的移动电话已经 40 岁
    HDU1056:HangOver
    Firefox OS 源码泄露!!!
    上网本 硬盘安装linux 最揪心的回忆
    103 Stacking Boxes
    ip2long之后有什么好处?
    mysql怎么创建,删除,查看索引?
    用mysql查询某字段是否有索引
  • 原文地址:https://www.cnblogs.com/lanyangsh/p/14455915.html
Copyright © 2011-2022 走看看