Cloneable的super.clone()是一个线程安全的方法吗?

时间:2014-12-12 09:27:50

标签: java multithreading

如果我有课程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中使用,并且处理程序被传递给两个线程AB如果同时线程A尝试克隆处理程序并且线程B尝试更改处理程序的公共变量?
例如。

Foo Class
    s = "Hello"
    n = "42"

此课程传递给同时运行的AB A想要克隆Foo Class,并且在1μs后B想要将n更改为43
克隆结果为s = "Hello" and n = "42" || n = "43"
更简单:super.clone()是线程安全的,还是我必须使用locksynchronized?如果我必须使用locksynchronized,这是使用它们的最佳方式吗?

3 个答案:

答案 0 :(得分:2)

你有点滥用术语“线程安全”。它并不意味着“同步”,这显然是你如何使用它。没有多少同步可以防止实现错误破坏线程安全性。作为一个例子,你编写的任何代码在没有任何锁定的情况下改变对象的代码都会明显违反对象的线程安全性,并且没有像Object.clone这样的库方法可以做的事情。

最终,线程安全始终掌握在实现者的手中,Object.clone()不会做任何事情来使你更难:它只是读取当前对象的状态并将其复制到新对象。它不会发布那个新对象。

答案 1 :(得分:1)

clone没有具体描述为线程安全,这意味着它不是。如果一个线程正在克隆该对象而另一个线程正在更改它,则克隆可能会以不一致的状态结束。

你可以在clone函数中获取锁定,但更好的方法是在调用clone的代码中获取它。

答案 2 :(得分:1)

如果两个线程试图在同一个Foo实例上执行此方法,那么它不是线程安全的。

您应该使用此实例创建一个互斥锁。例如,将执行此克隆方法的代码放在synchronized(fooInstance)块中。