java - AtomicInteger真的产生原子整数吗?

标签 java thread-safety sequences atomicinteger

我用Google搜索了AtomicInteger,然后看到有人说我们可以将AtomicInteger(AtomicLong)用于内存定序器(http://www.cs.hut.fi/u/tlilja/multicore/slides/java_multicore.pdf)。这是我的测试:

public class TestAtomicInteger {

public static void main(String[] args) {

    final AtomicInteger sequencer = new AtomicInteger(1);
    final Set<Integer> integers = new HashSet<>();
    //final Set<Integer> integers = new ConcurrentSkipListSet<>();


    final Runnable task = new Runnable() {

        @Override
        public void run() {
            int next = sequencer.getAndIncrement();
            integers.add(next);
            System.out.println(integers.size());
        }
    };
    for (int i = 0; i < 1000; i++) {
        Thread t = new Thread(task);
        t.start();
    }
}
}


多次运行此代码后,我发现有时原子输出的总和不是1000。这意味着getAndIncrement方法有DUPLICATE返回。

有人解释为什么吗?谢谢。

*注意:运行中功能。如果我使用System.out.println(next);有时我也看到一些缺少的音序器。 *

样品输出1:

1个
6
8
5
2
10
3
4
12
11
9
14
15
7
13
16
17
18岁
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
42
41
43
45
44
47
49
46
48
52
52
50
53
55
54
58
56
57
59
60
61
62
63
64
65岁
67
68
69
66
70
71
72
73
74
75
76
77
78
80
81
79
82
83
84
85
86
87
88
89
90
91
92
93
94
95
97
96
98
99
104
103
106
102
109
100
101
108
107
111
105
112
114
110
117
116
119
115
120
113
118
121
122
126
125
124
123
127
128
130
131
129
132
133
134
135
136
137
138
139
140
141
142
144
145
143
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
170
169
171
172
173
174
175
176
177
178
179
180
181
182
186
188
189
185
190
184
191
192
183
187
193
194
196
197
198
199
195
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
216
217
219
215
218
220
232
231
230
229
228
227
226
225
224
223
221
222
233
234
235
237
239
240
236
238
241
243
242
245
244
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
285
284
283
289
288
287
286
292
291
293
294
290
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
320
321
319
322
323
324
325
326
327
328
330
329
331
332
333
334
335
337
336
338
339
340
341
343
344
345
346
347
348
342
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
366
365
364
368
367
369
370
371
372
373
375
374
379
378
377
376
380
381
382
383
384
385
386
389
388
387
392
394
395
391
397
390
399
398
400
396
393
403
404
402
401
406
405
407
408
409
410
411
412
413
414
415
416
417
419
418
420
421
423
422
424
425
426
427
429
430
428
434
433
435
432
431
436
437
440
439
445
446
447
438
458
459
460
457
456
462
463
464
455
454
453
470
452
473
475
451
450
477
479
480
449
482
448
444
442
509
443
441
511
510
508
507
506
515
516
518
519
520
505
504
522
503
502
525
532
501
500
499
498
497
496
495
535
494
493
538
492
491
490
541
543
489
546
488
548
549
487
486
485
484
550
552
483
481
478
556
557
476
558
474
472
471
469
468
567
467
569
570
466
465
461
574
573
575
576
572
571
568
566
565
564
563
562
561
560
559
555
554
553
551
547
545
544
540
578
585
542
539
537
536
595
534
597
533
531
599
530
529
528
600
602
527
526
604
524
523
521
608
519
517
514
513
614
512
613
612
616
617
611
610
619
609
621
607
606
622
623
605
603
601
598
625
627
596
594
631
593
592
632
633
591
590
638
589
588
587
640
641
586
584
583
582
648
651
653
655
657
581
658
659
662
664
580
668
579
669
577
667
666
672
665
673
674
675
663
661
676
677
680
683
685
687
689
661
660
656
654
692
652
650
649
646
647
703
645
644
643
642
639
637
636
635
634
630
713
629
628
626
715
624
717
620
720
722
618
615
721
723
719
718
716
714
712
711
710
709
708
728
729
707
706
705
704
702
701
700
699
698
697
696
695
694
693
691
690
688
686
684
730
731
732
733
682
681
679
678
671
670
734
735
727
739
726
725
724
738
740
742
737
744
745
736
746
747
743
741
749
748
751
750
753
752
754
755
756
757
758
759
760
761
762
763
765
764
770
771
772
773
774
769
768
776
767
780
766
779
778
777
775
784
783
782
781
787
788
790
791
792
796
786
798
799
800
785
803
805
807
802
801
797
795
794
793
812
789
813
811
816
810
809
808
806
819
821
823
824
826
827
828
830
831
832
839
840
842
843
844
846
847
848
849
850
851
853
855
804
856
854
852
858
848
860
861
845
841
838
837
836
835
834
864
865
833
829
825
822
868
869
820
818
871
817
874
875
815
814
876
877
878
879
880
881
882
883
885年
887
888
889
891
892
894
896
898
901
902
903
905
906
875
873
872
870
867
866
863
862
859
857
904
900
899
897
895
893
907
890
908
886
884
909
910
911
912
913
914
927
928
926
929
931
932
934
938
939
940
942
925
944
945
924
923
922
948
921
949
920
919
918
915
916
917
951
950
947
946
943
941
937年
936
935
952
953
933
930
954
955
956
957年
958
959
960
961
962
963
964
965
966
968
969
970
971
972
985
986
987
967
989
988
990
985
984
991
983
982
993
981
980
979
978
977
976
975
974
973
995
995
992

最佳答案

代码的一个主要问题是将数字添加到不是线程安全的HashSet中。这就是您正在观察的原因。如果使用线程安全集合,则将获得预期的结果:

final Set<Integer> integers = new ConcurrentSkipListSet<>();


但这会引入额外的同步层。另一种选择是使用普通数组int[] numbers = new int[1000];并使用:numbers[next-1]++;来计算出现次数。

新代码供参考:

public static void main(String[] args) throws Exception {

    final AtomicInteger sequencer = new AtomicInteger(1);
    final int[] integers = new int[1000];

    final Runnable task = new Runnable() {

        @Override
        public void run() {
            int next = sequencer.getAndIncrement();
            integers[next-1]++;
        }
    };
    List<Thread> threads = new ArrayList<>();
    for (int i = 0; i < 1000; i++) {
        Thread t = new Thread(task);
        t.start();
        threads.add(t);
    }
    for (Thread t : threads) {
        t.join();
    }
    for (int i = 0; i < 1000; i++) {
        if (integers[i] != 1) System.out.println(i + " -> " + integers[i]);
    }
}

关于java - AtomicInteger真的产生原子整数吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20891176/

相关文章:

postgresql - 序列错误 postgres 9 到 10

java - 删除 Android webview 左右边距

java - 为什么饥饿单例模式是线程安全的

swift - 在 SceneKit 中使用不同的节点运行 SCNActions 序列

java - 在并发环境中创建单例的最佳实践?

java - 非同步静态方法和线程安全

c++ - 我想生成序列 1,3,8,22,60 ,164 中的第 n 项,顺序为 Order(1) 或 order of (nlogn)

java - Perl 使用 System.exit 从 Java Jar 返回代码

java - 我需要将映射放入 hibernate 配置中吗

java - 正则表达式匹配最短匹配而不是最长匹配