多线程面试题——Show Me The Difference (From Alibaba)

Show Me The Difference (From Alibaba)

公众号:小成同学在coding
文章如有问题欢迎指正

指出以下两段程序的差别,并分析

package com.mashibing.juc.c_35_QuestionsOfAlibaba;

public class ShowMeTheDifference {}

// 4.指出以下两段程序的差别,并分析

final class Accumulator {
    private double result = 0.0D;
    public void addAll( double[] values) {
        for(double value : values) {
            result += value;
        }
    }
}

final class Accumulator2 {
    private double result = 0.0D;
    public void addAll( double[] values) {
        double sum = 0.0D;
        for(double value : values) {
            sum += value;
        }
        result += sum;
    }
}

这两个程序都不能叫做线程安全。

第一种写法会暴露更多的中间值。

假如我们的double[] values数组里存放了3个数,在执行这个语句result += value时,当我们加到任何一个值的时候,在多线程的情况下,我们就能访问到result这个中间值;比如说,A线程Accumulator这个类来做计算,B线程也用Accumulator这个类来做计算,如果多线程访问的是同一个对象的话,中间这个result值,第一个线程所涉及到的,加了一次数组中的值,很容易就会被第二个线程读取到,如果有三个数,那么0.0D这个初始值在得到最终结果之前,会变化三次。

image-20211222205144699

第二种写法只会暴露一次最终的result值,因为它是将数组中的数全加完后,再赋值给result,如果A线程B线程同时访问,那么B线程最多只能读取到最后的值,读取不到变化的中间值。

image-20211222205636949

答案: 第二种写法比第一种写法出现不一致性的概率要小,因为我们在方法完成之前,读不到中间状态的脏数据

尽量少暴露线程计算过程的中间状态

能用范围小的变量,不用范围大的变量

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小成同学_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值