【发布时间】:2012-03-26 21:17:20
【问题描述】:
我之前回复了question 关于线程安全的问题,但没有得到明确的答案(我认为)。
所以我一直试图通过让数千个线程读取和写入该对象来说服自己设计被破坏(可见性) - 但我无法得到任何意想不到的东西。这显然不能证明它是线程安全的,可能只是证明我自己的局限性!
我了解重新排序的风险,但我看不出它在这种情况下如何应用,因为bar() 方法中的clone 实例是本地的,并且其字段的更改是在执行之前完成的使用return 向外界发布,之后实例实际上是不可变的。因此,查看返回对象的线程会看到它的 bar 字段已设置为正确的值...
所以我的问题是: 什么样的代码你能否展示一段使用IsItSafe的代码,它可能导致2个线程看到不同的值IsItSafe 的给定实例的bar 字段?
为了参考和阅读方便,我将代码复制到这里:
public class IsItSafe implements Cloneable {
private int foo;
private int bar;
public IsItSafe foo(int foo) {
IsItSafe clone = clone();
clone.foo = foo;
return clone;
}
public IsItSafe bar(int bar) {
IsItSafe clone = clone();
clone.bar = bar;
return clone;
}
public int getFoo() {
return foo;
}
public int getBar() {
return bar;
}
protected IsItSafe clone() {
try {
return (IsItSafe) super.clone();
} catch (CloneNotSupportedException e) {
throw new Error(e);
}
}
}
【问题讨论】:
-
该代码描述了一个不可变对象。不可变的东西总是线程安全的。
-
实际上它只是有效的不可变,必须安全发布以避免可见性问题。
标签: java multithreading thread-safety