AtomicInteger的updateAndGet是线程不安全的

public static void main(String[] args) {
        AtomicInteger integer = new AtomicInteger(0);
        ThreadPoolExecutor executor = new ThreadPoolExecutor(4, 4, 1, TimeUnit.SECONDS, new LinkedBlockingQueue<>(100));
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        list.stream()
                .map(i -> CompletableFuture.runAsync(() -> {
                            integer.updateAndGet(a -> {
                                System.out.println("当前数字:" + i);
                                return a + i;
                            });
                        }
                        , executor))
                .collect(Collectors.toList())
                .forEach(CompletableFuture::join);
        System.out.println(integer.get());
        executor.shutdown(); // 关闭线程池
    }

运行结果如下:

当前数字:2
当前数字:5
当前数字:6
当前数字:7
当前数字:8
当前数字:9
当前数字:10
当前数字:1
当前数字:3
当前数字:4
当前数字:1
当前数字:3
当前数字:3
当前数字:4
当前数字:4
55

可以看得出来,有一些方法重复打印了,说明integer.updateAndGet()这个方法被重复调用了。如果说integer.updateAndGet()这个方法传入的是一个外部方法,比如数据库入库操作并返回行数,就会出现线程不安全问题了,数据会重复插入。这是因为这个方法在多线程环境下,尝试更新值失败时,方法会被重新调用,导致重复执行。因此传入的外部方法不能对外部结果产生副作用,比如入库操作之类。

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值