• golang之slice并发访问



    slice在并发执行中不会报错, 但数据会丢失, 可以加锁解决; map在高并发执行中会直接报错, 需要加锁使用

    package main

    import (
     "fmt"
     "sort"
     "time"
    )

    var s []int

    func appendValue(i int) {
     s = append(s, i)
    }

    func main() {

     for i := 0; i < 10000; i++ {
      go appendValue(i)
     }

     sort.Ints(s) //给切片排序,先排完序再打印,

     for i, v := range s {
      fmt.Println(i, ":", v)

     }

     time.Sleep(5e9)

    }

    • 1

    输出为:

    0 : 0
    1 : 0
    2 : 0
    3 : 0
    4 : 0
    5 : 0
    6 : 0
    7 : 0
    8 : 0
    9 : 0
    10 : 0
    11 : 0
    12 : 0
    13 : 0
    14 : 0
    15 : 0
    16 : 0
    17 : 0
    18 : 0
    19 : 0
    20 : 0
    21 : 0
    22 : 0
    23 : 0
    24 : 0
    25 : 0
    26 : 0
    27 : 0
    28 : 0
    29 : 0
    30 : 0
    31 : 0
    32 : 0
    33 : 0
    34 : 0
    35 : 0
    36 : 0
    37 : 0
    38 : 0
    39 : 0
    40 : 0
    41 : 0
    42 : 0
    43 : 0
    44 : 0
    45 : 0
    46 : 0
    47 : 0
    48 : 0
    49 : 0
    50 : 0
    51 : 0
    52 : 0
    53 : 0
    54 : 0
    55 : 0
    56 : 0
    57 : 0
    58 : 0
    59 : 0
    60 : 0
    61 : 0
    62 : 0
    63 : 0
    64 : 0
    65 : 0
    66 : 0
    67 : 0
    68 : 0
    69 : 0
    70 : 0
    71 : 0
    72 : 0
    73 : 0
    74 : 0
    75 : 0
    76 : 0
    77 : 0
    78 : 0
    79 : 0
    80 : 0
    81 : 0
    82 : 0
    83 : 0
    84 : 0
    85 : 1
    86 : 2
    87 : 3
    88 : 6
    89 : 8
    90 : 12
    91 : 13
    92 : 14
    93 : 19
    94 : 28
    95 : 30
    96 : 31
    97 : 32
    98 : 33
    99 : 34
    100 : 35
    101 : 36
    102 : 44
    103 : 45
    104 : 46
    105 : 47
    106 : 48
    107 : 49
    108 : 50
    109 : 51
    110 : 52
    111 : 53
    112 : 54
    113 : 55
    114 : 56
    115 : 57
    116 : 58
    117 : 59
    118 : 60
    119 : 61
    120 : 62
    121 : 63
    122 : 64
    123 : 65
    124 : 66
    125 : 67
    126 : 68
    127 : 69
    128 : 70
    129 : 71
    130 : 72
    131 : 73
    132 : 74
    133 : 75
    134 : 76
    135 : 77
    136 : 78
    137 : 79
    138 : 80
    139 : 81
    140 : 82
    141 : 83
    142 : 84
    143 : 85
    144 : 86
    145 : 87
    146 : 88
    147 : 89
    148 : 90
    149 : 91
    150 : 92
    151 : 93
    152 : 94
    153 : 95
    154 : 96
    155 : 97
    156 : 98
    157 : 99
    158 : 100
    159 : 101
    160 : 102
    161 : 103
    162 : 104
    163 : 105
    164 : 106
    165 : 107
    166 : 108
    167 : 109
    168 : 110
    169 : 111
    ...

    8309 : 9970
    8310 : 9971
    8311 : 9972
    8312 : 9973
    8313 : 9974
    8314 : 9976
    8315 : 9977
    8316 : 9978
    8317 : 9979
    8318 : 9980
    8319 : 9981
    8320 : 9982
    8321 : 9983
    8322 : 9984
    8323 : 9985
    8324 : 9986
    8325 : 9987
    8326 : 9988
    8327 : 9989
    8328 : 9990
    8329 : 9991
    8330 : 9992
    8331 : 9993
    8332 : 9995
    8333 : 9996
    8334 : 9994
    8335 : 9997
    8336 : 9998
    8337 : 9999

    • 1

    没有到 9999 : 9999


    加锁之后:


    package main

    import (
     "fmt"
     "sort"
     "sync"
     "time"
    )

    var s []int
    var lock sync.Mutex

    func appendValue(i int) {
     lock.Lock()
     s = append(s, i)
     lock.Unlock()
    }

    func main() {

     for i := 0; i < 10000; i++ {
      go appendValue(i)
     }

     sort.Ints(s) //给切片排序,先排完序再打印,
     
     for i, v := range s {
      fmt.Println(i, ":", v)

     }

     time.Sleep(5e9)

    }


    • 1

    输出为:

    0 : 0
    1 : 1
    2 : 2
    3 : 3
    4 : 4
    5 : 5
    6 : 6
    7 : 7
    8 : 8
    9 : 9
    10 : 10
    11 : 11
    12 : 12
    13 : 13
    14 : 14

    ...

    9992 : 9992
    9993 : 9993
    9994 : 9994
    9995 : 9995
    9996 : 9996
    9997 : 9997
    9998 : 9998
    9999 : 9999

    • 1

    参考:

    golang并发安全: slice和map并发不安全,及其解决方法




    米哈游面试:

    package main

    import (
     "fmt"
    )

    func main() {

     var sli []int

     for i := 0; i < 10; i++ {

      go func() {
       //for j := 0; j < 10; j++ {
       sli = append(sli, 1)
       //}
      }()
     }

     //time.Sleep(time.Second)
     fmt.Println(len(sli))

    }
    • 1

    这样一般会是0



    package main

    import (
     "fmt"
    )

    func main() {

     var sli []int

     for i := 0; i < 10; i++ {

      go func() {
       for j := 0; j < 10; j++ {
        sli = append(sli, 1)
       }
      }()
     }

     //time.Sleep(time.Second)
     fmt.Println(len(sli))

    }

    • 1

    这样一般也是0


    package main

    import (
     "fmt"
     "time"
    )

    func main() {

     var sli []int

     for i := 0; i < 10; i++ {

      go func() {
       //for j := 0; j < 10; j++ {
       sli = append(sli, 1)
       //}
      }()
     }

     time.Sleep(time.Millisecond)
     fmt.Println(len(sli))

    }
    • 1

    这样一般<10


    package main

    import (
     "fmt"
     "time"
    )

    func main() {

     var sli []int

     for i := 0; i < 10; i++ {

      go func() {
       for j := 0; j < 10; j++ {
        sli = append(sli, 1)
       }
      }()
     }

     time.Sleep(time.Microsecond)
     fmt.Println(len(sli))

    }
    • 1

    一般<100

    本文由 mdnice 多平台发布

  • 相关阅读:
    ES6数组的方法及伪数组转数组方法
    【C++模块实现】| 【09】线程模块及线程池的实现
    RocketMQ源码(十九)之消费者Rebalance
    PHP韩语学习网站用wamp、phpstudy运行定制开发mysql数据库BS模式
    哨兵模式(sentinel)
    [ MSF使用实例 ] 利用永恒之蓝(MS17-010)漏洞导致windows靶机蓝屏并获取靶机权限
    Shell学习--printf命令
    Spring核心系列——多yaml数据读取,@Value day1-1
    基于web的照片数码冲印网站
    【Java 进阶篇】使用 JDBCTemplate 执行 DML 语句详解
  • 原文地址:https://blog.csdn.net/techdashen/article/details/133801242