Java并发编程(Java Concurrency)(10)- 线程安全与不变性(Thread Safety and Immutability)

原文链接:http://tutorials.jenkov.com/java-concurrency/thread-safety-and-immutability.html

摘要:这是翻译自一个大概30个小节的关于Java并发编程的入门级教程,原作者Jakob Jenkov,译者Zhenning Lang,转载请注明出处,thanks and have a good time here~~~(希望自己不要留坑)

竞争只发生在多个线程写相同资源的时候,如果仅仅是多个线程读取同一个资源,则不会发生竞争。

那么可以通过使共享对象保持不变(immutable)来让使用它的线程无法更新这个对象,从而达到线程安全,例如:

public class ImmutableValue{

    private int value = 0;
    public ImmutableValue(int value){
        this.value = value;
    }

    public int getValue(){
        return this.value;
    }
}

上例中在构造函数中给 value 赋值,而由于没有 setter 方法,value 的值也无法被改变。一旦 ImmutableValue 的实例被创建,其 value 就保持不变,我们称之为具有不变性。

如果需要对 ImmutableValue 的实例进行一些操作,那么可以通过返回一个具有操作后结果的新的实例来实现不变性,下例展示了 add 操作是如何保持不变性的:

public class ImmutableValue{

    private int value = 0;

    public ImmutableValue(int value){
        this.value = value;
    }

    public int getValue(){
        return this.value;
    }

    public ImmutableValue add(int valueToAdd){
        return new ImmutableValue(this.value + valueToAdd);
    }
}

请仔细分析 add() 方法是如何通过返回一个新的 ImmutableValue 实例保持不变性的。

实例的引用是不安全的(The Reference is not Thread Safe)!

非常值得注意的一点是,即便一个对象本身是具有不变性并且线程安全的,对这个对象的引用可能并不是线程安全的。例如:

public class Calculator{
    private ImmutableValue currentValue = null;

    public ImmutableValue getValue(){
        return currentValue;
    }

    public void setValue(ImmutableValue newValue){
        this.currentValue = newValue;
    }

    public void add(int newValue){
        this.currentValue = this.currentValue.add(newValue);
    }
}

Calculator 类包含一个 ImmutableValue 实例的引用。如果仔细分析 setValue() 和 add() 方法,我们可以发现虽然 ImmutableValue 类本身是具有不变性的,但 Calculator 类却不具有不变性,也并非线程安全的。换言之,虽然具有不变性的类本身是线程安全,但对其引用的使用却不一定是线程安全的。这是想通过不变性达到线程安全目的所需要牢记的事。

为了使 Calculator 类变得线程俺去,可以将 getValue(), setValue(), 和 add() 方法声明成同步的(synchronized)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值