[英]Is super.clone() of Cloneable a thread safe method?
如果我有一个类Foo
public class Foo implements Serializable, Cloneable {
public Foo() {}
protected String s;
protected int n;
public Foo clone() {
return (Foo) super.clone();
}
public String getS() {
return s;
}
public void setS(String s) {
this.s = s;
}
public String getN() {
return n;
}
public void setN(int n) {
this.n = n;
}
}
它在MyClass
使用,并且将处理程序传递给两个线程A
和B
,如果线程A同时尝试克隆处理程序,而线程B尝试更改处理程序的公共变量,会发生什么情况呢?
例如
Foo Class
s = "Hello"
n = "42"
此类传递给同时运行的A
和B
A
想要克隆Foo Class
并且在1 µs之后B
想要将n更改为43
。
克隆结果将为s = "Hello" and n = "42" || n = "43"
s = "Hello" and n = "42" || n = "43"
?
更简单: super.clone()
是线程安全的,还是我必须使用lock
或synchronized
? 如果我必须使用lock
或synchronized
,那是使用它们的最佳方法?
您稍微误用了“线程安全”一词。 这并不意味着“同步”,这显然是您使用它的方式。 同步量无法防止实现错误破坏线程安全。 例如,您编写的任何在不持有任何锁的情况下对对象进行变异的代码都将明显违反该对象的线程安全性,并且像Object.clone
这样的库方法对此无能为力。
最终,线程安全性始终由实现者掌握, Object.clone()
不会为您带来任何困难:它所做的只是读取当前对象的状态并将其复制到新对象。 它不会发布该新对象。
没有将clone
专门描述为线程安全的,这意味着不是。 如果一个线程正在克隆对象,而另一个线程正在更改对象,则克隆可能会以不一致的状态结束。
您可以在clone
函数中获取一个锁,但是更好的方法是在调用clone
的代码中获取它。
不,如果两个线程试图在相同的Foo实例上执行此方法,则它不是线程安全的。
您应该使用该实例创建一个互斥锁。例如,将执行此克隆方法的代码放置在synced(fooInstance)块中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.