您的位置:首页 > 其它

线程安全及不可变性

2016-09-02 17:06 246 查看
线程安全中一个一定要注意的地方就是不可变性。什么意思呢?就是说一个对象是不可变的,那么对这个对象的操作就一定是线程安全的嘛?答案是否定的。举个栗子看看。

1、创建一个不可变对象

package Immutable;

/**
* Created by carrot on 16/9/2.
*/
public class ImmutableObject {

private String azeroth;

public ImmutableObject(String azeroth){
this.azeroth = azeroth;
}

public String getAzeroth() {
return azeroth;
}

public ImmutableObject add(String str) {
return new ImmutableObject(this.azeroth + str);
}
}

注意:ImmutableObject类是一个不可变类,顾名思义,一旦创建一个ImmutableObject类的实例,那么这个实例就是不可变的。因为ImmutableObject类中只有get方法,没有set方法,因此一段创建实例,这个实例就不可变。其次。add方法是一个创建新实例的方法,因此调用add方法以后,我们得到的是一个新的对象,而并没有改变原来的实例。因此ImmutableObject类是不可变的。

但是,ImmutableObject类是不可变的,那么我们使用ImmutableObject的实例就一定是线程安全的么?不是的。因为ImmutableObject类的实例是线程安全的,但是当我们使用ImmutableObject类的实例时,一般都是通过引用来使用的。那么,一定要注意对象的引用!

package Immutable;

/**
* Created by carrot on 16/9/2.
*/
public class UseImmutableObject {

private ImmutableObject immutableObject;

public ImmutableObject getImmutableObject() {
return immutableObject;
}

public void setImmutableObject(ImmutableObject immutableObject) {
this.immutableObject = immutableObject;
}

public void add(String str) {
this.immutableObject = immutableObject.add(str);
}
}<span style="color:#ff6666;font-weight: bold;">
</span>
ImmutableObject类的实例是不可变的,但是当我们使用时,是通过immutableObject这个引用来使用这个实例的。但是在我们使用这个引用时,可能通过使用ImmutableObject类的这个类改变了这个immutableObject引用,导致线程不安全。

因此,当我们使用一个线程安全的类的实例时,并不一定是线程安全的。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息