同步锁定对象

时间:2012-09-17 09:20:37

标签: java methods synchronization locking

我对与Java方法同步和对象锁定有关的事情感到好奇。

当您调用synchronized方法时,根据我的理解,它会在方法调用期间锁定整个对象。

这是否意味着您只需要同步将数据写入对象的方法,而不是从对象中读取数据?

public class testclass {

    private ArrayList<String> data;

    public ArrayList<String> getData() {
        return data;
    }

    public synchronized void setData(ArrayList<String> data) {
        this.data = data;
    }
}

基本上上面的代码是线程安全的(因为在运行setData方法时,testclass对象被锁定)?或者我也应该同步getData方法?

3 个答案:

答案 0 :(得分:3)

  

这是否意味着您只需要同步将数据写入对象的方法,而不是从对象中读取数据?

否 - 如果您不同步读取,则没有任何可见性保证(您可以获得该对象的陈旧版本)。

注意:在您的情况下,您不需要使用synchronized关键字,因为每个方法都是原子的 - 您可以简单地使data变为volatile。

答案 1 :(得分:2)

锁不是锁定对象本身,而是与对象关联的监视器。在你的情况下,即使方法getData的同步也不会使testclass线程安全,因为它会将“data”字段的实例返回到wild world,并且许多线程可能以不可预测的顺序对对象做任何他们想做的事。

为了遵循“可见性”,您需要使“数据”易变,或者同步两种方法 - 因为JVM可以以任何方式自由优化字节码,这使得某些线程可以看到“陈旧”数据

答案 2 :(得分:1)

如果您没有synchronize getData()方法,当一个线程首先首先调用getData()而另一个线程想要执行writeData()方法时,您有什么保证?线程未锁定。因此不是线程安全的。

[编辑] 和其他指定的一样,返回非易失性Data对象也不是线程安全的,可以在此类之外以非线程安全的方式进行修改