C# 浅析并行任务同步机制——Interlocked

一、定义:为多个线程共享的变量提供原子操作。

                  i++和i-- 这种原子操作,都不是线程安全的,它的操作包括从内存中读取一个值,给值递增或递减,然后再将它存储回内存。这些操作都有可能会被线程调度器打断。

                  以线程安全的方式递增、递减、交换和读取值的方法。

二、优缺点:

                   优点:与其他技术相比,较快。

                   缺点:只能用于简单的同步问题。

三、例子

public int State
{
   get
   {
      lock(this)
      {
         return ++_state;
      }
   }
}

//使用Interlocked

public int State
{
   get => Interlocked.Increment(ref _state);
}

 四、下面使用一个综合应用例子,用来说明原子操作的线程安全性

         Parallel:用来实现并行任务

        Thread:用来创建多线程

        ConcurrentDictionary:线程安全字典,用来存放访问次数的存放。

        Interlocked:用来实现原子操作

        场景:实现一个人数访问的次数,每一个线程代表一次访问,线程安全的操作,应该是最后的访问人数和总数相等,不安全的操作,访问的次数有重复。

        访问人数实体,声明了一个线程安全的递增操作,一个线程不安全的递增操作。

public class VisitNum
{
    private int _stateNotSafe;
    private int _stateSafe;
    /// 
    /// 线程不安全的递增操作
    /// 
    public int StateNotSafe
    {
        get { return ++_stateNotSafe; }
    }
    /// 
    /// 线程安全的递增操作
    /// 
    public int StateSafe
    {
        get { return Interlocked.Increment(ref _stateSafe); }
    }
}

     实现并行多线程请求,实现访问人数的递增

class Program
{
    static void Main(string[] args)
    {
        VisitNum vi = new VisitNum();
        ConcurrentDictionary conNotSafe = new ConcurrentDictionary();
        ConcurrentDictionary conSafe = new ConcurrentDictionary();
        ParallelLoopResult result = Parallel.For(1, 300, (i) =>
        {
            Thread thread = new Thread(new ThreadStart(() =>
            {
                int sleep = 8 * 1000;
                Thread.Sleep(sleep);
                int nSafe = vi.StateNotSafe;
                conNotSafe.AddOrUpdate(nSafe, 1, (k, v) => {
                    v = v +1;
                    return v;
                });

                int Safe = vi.StateSafe;
                conSafe.AddOrUpdate(Safe, 1, (k, v) => {
                    v = v + 1;
                    return v;
                });
                Console.WriteLine($"线程ID: {Thread.CurrentThread.ManagedThreadId} 访问人数:{nSafe} 安全访问人数:{Safe}");
            }));
            thread.Start();
       });
       Console.ReadLine();
       Console.WriteLine("不安全线程 begin");
       foreach(var item in conNotSafe)
       {
           if (item.Value > 1)
           {
              Console.WriteLine($"key:{item.Key} ; value:{item.Value}");
           }

       }
       Console.WriteLine("不安全线程 end");
       Console.WriteLine("安全线程 begin");
       foreach (var item in conSafe)
       {
           if (item.Value > 1)
           {
               Console.WriteLine($"key:{item.Key} ; value:{item.Value}");
           }

        }
            Console.WriteLine("安全线程 end");
            Console.ReadLine();
   }
}

运行结果,

线程ID: 14 访问人数:1 安全访问人数:1
线程ID: 20 访问人数:2 安全访问人数:2
线程ID: 11 访问人数:3 安全访问人数:3
线程ID: 25 访问人数:4 安全访问人数:4
线程ID: 27 访问人数:5 安全访问人数:5
线程ID: 17 访问人数:6 安全访问人数:6
线程ID: 30 访问人数:7 安全访问人数:7
线程ID: 21 访问人数:8 安全访问人数:8
线程ID: 31 访问人数:10 安全访问人数:10
线程ID: 24 访问人数:9 安全访问人数:9
线程ID: 29 访问人数:11 安全访问人数:11
线程ID: 32 访问人数:12 安全访问人数:12
线程ID: 23 访问人数:13 安全访问人数:13
线程ID: 28 访问人数:14 安全访问人数:14
线程ID: 36 访问人数:15 安全访问人数:15
线程ID: 39 访问人数:17 安全访问人数:16
线程ID: 33 访问人数:16 安全访问人数:17
线程ID: 34 访问人数:18 安全访问人数:18
线程ID: 37 访问人数:19 安全访问人数:19
线程ID: 35 访问人数:20 安全访问人数:20
线程ID: 41 访问人数:21 安全访问人数:21
线程ID: 40 访问人数:22 安全访问人数:22
线程ID: 38 访问人数:23 安全访问人数:23
线程ID: 43 访问人数:24 安全访问人数:24
线程ID: 47 访问人数:25 安全访问人数:25
线程ID: 44 访问人数:26 安全访问人数:26
线程ID: 64 访问人数:27 安全访问人数:27
线程ID: 60 访问人数:29 安全访问人数:28
线程ID: 42 访问人数:28 安全访问人数:29
线程ID: 58 访问人数:30 安全访问人数:30
线程ID: 45 访问人数:32 安全访问人数:32
线程ID: 52 访问人数:31 安全访问人数:31
线程ID: 57 访问人数:33 安全访问人数:33
线程ID: 51 访问人数:34 安全访问人数:34
线程ID: 46 访问人数:38 安全访问人数:38
线程ID: 54 访问人数:35 安全访问人数:35
线程ID: 53 访问人数:37 安全访问人数:37
线程ID: 59 访问人数:36 安全访问人数:36
线程ID: 56 访问人数:40 安全访问人数:40
线程ID: 67 访问人数:39 安全访问人数:39
线程ID: 65 访问人数:41 安全访问人数:41
线程ID: 66 访问人数:43 安全访问人数:43
线程ID: 55 访问人数:42 安全访问人数:42
线程ID: 63 访问人数:45 安全访问人数:45
线程ID: 61 访问人数:44 安全访问人数:44
线程ID: 68 访问人数:46 安全访问人数:46
线程ID: 69 访问人数:48 安全访问人数:48
线程ID: 71 访问人数:47 安全访问人数:47
线程ID: 73 访问人数:48 安全访问人数:49
线程ID: 62 访问人数:48 安全访问人数:50
线程ID: 77 访问人数:49 安全访问人数:51
线程ID: 76 访问人数:50 安全访问人数:52
线程ID: 74 访问人数:51 安全访问人数:53
线程ID: 70 访问人数:52 安全访问人数:54
线程ID: 75 访问人数:53 安全访问人数:55
线程ID: 79 访问人数:54 安全访问人数:56
线程ID: 72 访问人数:56 安全访问人数:58
线程ID: 78 访问人数:55 安全访问人数:57
线程ID: 82 访问人数:58 安全访问人数:60
线程ID: 86 访问人数:58 安全访问人数:61
线程ID: 80 访问人数:58 安全访问人数:62
线程ID: 81 访问人数:57 安全访问人数:59
线程ID: 85 访问人数:60 安全访问人数:63
线程ID: 84 访问人数:60 安全访问人数:65
线程ID: 83 访问人数:59 安全访问人数:64
线程ID: 88 访问人数:61 安全访问人数:66
线程ID: 87 访问人数:63 安全访问人数:68
线程ID: 95 访问人数:62 安全访问人数:67
线程ID: 99 访问人数:64 安全访问人数:69
线程ID: 92 访问人数:68 安全访问人数:73
线程ID: 93 访问人数:65 安全访问人数:70
线程ID: 91 访问人数:67 安全访问人数:72
线程ID: 96 访问人数:66 安全访问人数:71
线程ID: 90 访问人数:69 安全访问人数:74
线程ID: 94 访问人数:73 安全访问人数:78
线程ID: 97 访问人数:71 安全访问人数:77
线程ID: 89 访问人数:72 安全访问人数:79
线程ID: 98 访问人数:70 安全访问人数:76
线程ID: 106 访问人数:70 安全访问人数:75
线程ID: 104 访问人数:74 安全访问人数:80
线程ID: 105 访问人数:75 安全访问人数:81
线程ID: 110 访问人数:76 安全访问人数:83
线程ID: 103 访问人数:77 安全访问人数:84
线程ID: 102 访问人数:77 安全访问人数:82
线程ID: 108 访问人数:78 安全访问人数:85
线程ID: 109 访问人数:80 安全访问人数:87
线程ID: 100 访问人数:79 安全访问人数:86
线程ID: 117 访问人数:81 安全访问人数:88
线程ID: 113 访问人数:82 安全访问人数:89
线程ID: 111 访问人数:83 安全访问人数:90
线程ID: 107 访问人数:84 安全访问人数:91
线程ID: 101 访问人数:85 安全访问人数:92
线程ID: 112 访问人数:86 安全访问人数:93
线程ID: 116 访问人数:87 安全访问人数:97
线程ID: 126 访问人数:87 安全访问人数:99
线程ID: 115 访问人数:87 安全访问人数:98
线程ID: 114 访问人数:87 安全访问人数:94
线程ID: 119 访问人数:87 安全访问人数:96
线程ID: 120 访问人数:88 安全访问人数:100
线程ID: 125 访问人数:87 安全访问人数:95
线程ID: 135 访问人数:89 安全访问人数:101
线程ID: 133 访问人数:90 安全访问人数:102
线程ID: 132 访问人数:91 安全访问人数:103
线程ID: 122 访问人数:92 安全访问人数:104
线程ID: 118 访问人数:93 安全访问人数:105
线程ID: 134 访问人数:95 安全访问人数:106
线程ID: 128 访问人数:95 安全访问人数:109
线程ID: 129 访问人数:94 安全访问人数:107
线程ID: 131 访问人数:95 安全访问人数:108
线程ID: 142 访问人数:96 安全访问人数:110
线程ID: 127 访问人数:103 安全访问人数:116
线程ID: 136 访问人数:100 安全访问人数:114
线程ID: 139 访问人数:102 安全访问人数:113
线程ID: 124 访问人数:97 安全访问人数:111
线程ID: 121 访问人数:98 安全访问人数:112
线程ID: 137 访问人数:101 安全访问人数:115
线程ID: 123 访问人数:99 安全访问人数:117
线程ID: 148 访问人数:104 安全访问人数:118
线程ID: 141 访问人数:105 安全访问人数:119
线程ID: 138 访问人数:106 安全访问人数:121
线程ID: 150 访问人数:108 安全访问人数:122
线程ID: 154 访问人数:107 安全访问人数:120
线程ID: 130 访问人数:110 安全访问人数:124
线程ID: 145 访问人数:109 安全访问人数:123
线程ID: 140 访问人数:112 安全访问人数:126
线程ID: 147 访问人数:111 安全访问人数:125
线程ID: 143 访问人数:113 安全访问人数:127
线程ID: 144 访问人数:114 安全访问人数:128
线程ID: 146 访问人数:115 安全访问人数:129
线程ID: 151 访问人数:116 安全访问人数:131
线程ID: 159 访问人数:119 安全访问人数:134
线程ID: 152 访问人数:116 安全访问人数:130
线程ID: 153 访问人数:118 安全访问人数:133
线程ID: 157 访问人数:117 安全访问人数:132
线程ID: 158 访问人数:120 安全访问人数:136
线程ID: 155 访问人数:120 安全访问人数:135
线程ID: 161 访问人数:121 安全访问人数:137
线程ID: 149 访问人数:122 安全访问人数:138
线程ID: 156 访问人数:124 安全访问人数:139
线程ID: 162 访问人数:123 安全访问人数:140
线程ID: 165 访问人数:125 安全访问人数:141
线程ID: 168 访问人数:126 安全访问人数:142
线程ID: 160 访问人数:127 安全访问人数:144
线程ID: 166 访问人数:128 安全访问人数:146
线程ID: 170 访问人数:128 安全访问人数:143
线程ID: 163 访问人数:128 安全访问人数:145
线程ID: 171 访问人数:128 安全访问人数:147
线程ID: 172 访问人数:129 安全访问人数:148
线程ID: 167 访问人数:130 安全访问人数:149
线程ID: 173 访问人数:133 安全访问人数:150
线程ID: 181 访问人数:131 安全访问人数:152
线程ID: 180 访问人数:139 安全访问人数:159
线程ID: 177 访问人数:134 安全访问人数:153
线程ID: 164 访问人数:136 安全访问人数:156
线程ID: 169 访问人数:132 安全访问人数:154
线程ID: 182 访问人数:138 安全访问人数:158
线程ID: 176 访问人数:140 安全访问人数:160
线程ID: 174 访问人数:141 安全访问人数:161
线程ID: 183 访问人数:135 安全访问人数:155
线程ID: 179 访问人数:132 安全访问人数:151
线程ID: 175 访问人数:137 安全访问人数:157
线程ID: 186 访问人数:142 安全访问人数:162
线程ID: 193 访问人数:143 安全访问人数:163
线程ID: 190 访问人数:144 安全访问人数:164
线程ID: 185 访问人数:145 安全访问人数:165
线程ID: 194 访问人数:147 安全访问人数:166
线程ID: 196 访问人数:147 安全访问人数:168
线程ID: 184 访问人数:148 安全访问人数:169
线程ID: 178 访问人数:146 安全访问人数:167
线程ID: 200 访问人数:151 安全访问人数:174
线程ID: 205 访问人数:149 安全访问人数:173
线程ID: 213 访问人数:159 安全访问人数:183
线程ID: 202 访问人数:158 安全访问人数:182
线程ID: 208 访问人数:154 安全访问人数:178
线程ID: 201 访问人数:157 安全访问人数:181
线程ID: 187 访问人数:153 安全访问人数:177
线程ID: 197 访问人数:152 安全访问人数:176
线程ID: 188 访问人数:150 安全访问人数:175
线程ID: 199 访问人数:156 安全访问人数:180
线程ID: 191 访问人数:160 安全访问人数:184
线程ID: 192 访问人数:149 安全访问人数:171
线程ID: 195 访问人数:150 安全访问人数:170
线程ID: 189 访问人数:150 安全访问人数:172
线程ID: 198 访问人数:155 安全访问人数:179
线程ID: 203 访问人数:161 安全访问人数:185
线程ID: 215 访问人数:162 安全访问人数:186
线程ID: 217 访问人数:163 安全访问人数:187
线程ID: 214 访问人数:164 安全访问人数:189
线程ID: 207 访问人数:168 安全访问人数:192
线程ID: 212 访问人数:169 安全访问人数:193
线程ID: 209 访问人数:166 安全访问人数:190
线程ID: 218 访问人数:167 安全访问人数:191
线程ID: 223 访问人数:165 安全访问人数:188
线程ID: 216 访问人数:170 安全访问人数:194
线程ID: 211 访问人数:171 安全访问人数:195
线程ID: 204 访问人数:172 安全访问人数:196
线程ID: 220 访问人数:173 安全访问人数:197
线程ID: 206 访问人数:174 安全访问人数:200
线程ID: 221 访问人数:175 安全访问人数:198
线程ID: 219 访问人数:174 安全访问人数:199
线程ID: 225 访问人数:176 安全访问人数:201
线程ID: 222 访问人数:177 安全访问人数:202
线程ID: 210 访问人数:178 安全访问人数:203
线程ID: 235 访问人数:179 安全访问人数:204
线程ID: 228 访问人数:182 安全访问人数:206
线程ID: 224 访问人数:180 安全访问人数:205
线程ID: 230 访问人数:184 安全访问人数:209
线程ID: 227 访问人数:181 安全访问人数:207
线程ID: 226 访问人数:183 安全访问人数:208
线程ID: 231 访问人数:187 安全访问人数:213
线程ID: 238 访问人数:186 安全访问人数:211
线程ID: 232 访问人数:188 安全访问人数:215
线程ID: 229 访问人数:186 安全访问人数:212
线程ID: 234 访问人数:189 安全访问人数:216
线程ID: 239 访问人数:186 安全访问人数:210
线程ID: 242 访问人数:185 安全访问人数:214
线程ID: 241 访问人数:190 安全访问人数:217
线程ID: 236 访问人数:191 安全访问人数:218
线程ID: 237 访问人数:192 安全访问人数:219
线程ID: 233 访问人数:193 安全访问人数:220
线程ID: 244 访问人数:194 安全访问人数:221
线程ID: 245 访问人数:195 安全访问人数:224
线程ID: 249 访问人数:196 安全访问人数:225
线程ID: 240 访问人数:197 安全访问人数:226
线程ID: 243 访问人数:195 安全访问人数:223
线程ID: 253 访问人数:200 安全访问人数:230
线程ID: 247 访问人数:198 安全访问人数:227
线程ID: 256 访问人数:198 安全访问人数:229
线程ID: 248 访问人数:196 安全访问人数:222
线程ID: 258 访问人数:199 安全访问人数:228
线程ID: 251 访问人数:201 安全访问人数:231
线程ID: 250 访问人数:202 安全访问人数:232
线程ID: 246 访问人数:205 安全访问人数:235
线程ID: 255 访问人数:203 安全访问人数:234
线程ID: 252 访问人数:206 安全访问人数:236
线程ID: 254 访问人数:204 安全访问人数:233
线程ID: 261 访问人数:207 安全访问人数:237
线程ID: 262 访问人数:208 安全访问人数:238
线程ID: 259 访问人数:209 安全访问人数:239
线程ID: 257 访问人数:210 安全访问人数:240
线程ID: 269 访问人数:212 安全访问人数:242
线程ID: 260 访问人数:211 安全访问人数:241
线程ID: 263 访问人数:213 安全访问人数:243
线程ID: 268 访问人数:214 安全访问人数:244
线程ID: 264 访问人数:215 安全访问人数:245
线程ID: 266 访问人数:216 安全访问人数:246
线程ID: 271 访问人数:217 安全访问人数:247
线程ID: 272 访问人数:218 安全访问人数:248
线程ID: 265 访问人数:219 安全访问人数:249
线程ID: 277 访问人数:223 安全访问人数:254
线程ID: 273 访问人数:221 安全访问人数:250
线程ID: 278 访问人数:222 安全访问人数:252
线程ID: 267 访问人数:220 安全访问人数:251
线程ID: 270 访问人数:225 安全访问人数:255
线程ID: 274 访问人数:224 安全访问人数:253
线程ID: 279 访问人数:226 安全访问人数:257
线程ID: 276 访问人数:227 安全访问人数:256
线程ID: 286 访问人数:228 安全访问人数:258
线程ID: 280 访问人数:230 安全访问人数:260
线程ID: 281 访问人数:229 安全访问人数:259
线程ID: 275 访问人数:231 安全访问人数:261
线程ID: 282 访问人数:233 安全访问人数:263
线程ID: 289 访问人数:232 安全访问人数:262
线程ID: 287 访问人数:234 安全访问人数:264
线程ID: 284 访问人数:235 安全访问人数:265
线程ID: 285 访问人数:236 安全访问人数:266
线程ID: 283 访问人数:237 安全访问人数:267
线程ID: 297 访问人数:238 安全访问人数:268
线程ID: 288 访问人数:240 安全访问人数:270
线程ID: 295 访问人数:239 安全访问人数:269
线程ID: 291 访问人数:241 安全访问人数:271
线程ID: 300 访问人数:243 安全访问人数:273
线程ID: 293 访问人数:242 安全访问人数:272
线程ID: 290 访问人数:244 安全访问人数:274
线程ID: 294 访问人数:245 安全访问人数:275
线程ID: 292 访问人数:246 安全访问人数:276
线程ID: 296 访问人数:247 安全访问人数:277
线程ID: 299 访问人数:248 安全访问人数:278
线程ID: 301 访问人数:250 安全访问人数:280
线程ID: 302 访问人数:249 安全访问人数:279
线程ID: 303 访问人数:251 安全访问人数:281
线程ID: 298 访问人数:252 安全访问人数:282
线程ID: 305 访问人数:253 安全访问人数:284
线程ID: 306 访问人数:253 安全访问人数:283
线程ID: 304 访问人数:254 安全访问人数:285
线程ID: 309 访问人数:255 安全访问人数:286
线程ID: 314 访问人数:256 安全访问人数:287
线程ID: 310 访问人数:257 安全访问人数:288
线程ID: 307 访问人数:258 安全访问人数:289
线程ID: 320 访问人数:259 安全访问人数:290
线程ID: 316 访问人数:260 安全访问人数:291
线程ID: 312 访问人数:261 安全访问人数:292
线程ID: 308 访问人数:262 安全访问人数:293
线程ID: 311 访问人数:263 安全访问人数:294
线程ID: 315 访问人数:264 安全访问人数:295
线程ID: 317 访问人数:265 安全访问人数:296
线程ID: 318 访问人数:266 安全访问人数:297
线程ID: 313 访问人数:267 安全访问人数:298
线程ID: 319 访问人数:268 安全访问人数:299

不安全线程 begin
key:48 ; value:3
key:58 ; value:3
key:60 ; value:2
key:70 ; value:2
key:77 ; value:2
key:87 ; value:6
key:95 ; value:3
key:116 ; value:2
key:120 ; value:2
key:128 ; value:4
key:132 ; value:2
key:147 ; value:2
key:149 ; value:2
key:150 ; value:3
key:174 ; value:2
key:186 ; value:3
key:195 ; value:2
key:196 ; value:2
key:198 ; value:2
key:253 ; value:2
不安全线程 end
安全线程 begin
安全线程 end

运行的结果,每次不一定相同。当运行结果中,不安全线程,中存在数据,而安全线程中,不存在重复的数据。

你可能感兴趣的:(技术积累,多线程,java,c++,servlet)