同步方法是否对此进行锁定

时间:2014-12-06 19:20:34

标签: java thread-safety

我正在阅读一本Java书,并发现了以下问题。

在下面的代码中,类线程是否安全?

public class Queen   
{
    public int x;
    public synchronized int getX()
    {
        return x;
    }
    public synchronized void setX(int x)
    {
        this.x = x;
    }
    public static void main(String args[]) 
    {
    }
}

我的回答是肯定的,因为只有两个方法都是同步的,所以当其中一个方法正在运行时,它会锁定对象,而另一个方法无法运行。

然而,官方答案是否定的,并且解释是变量int x是公共的并且可以由线程修改而另一个线程在其中一个同步方法中。那可能吗??同步方法是否在此处保留线程,这意味着该对象中的所有内容都包括公共变量?

3 个答案:

答案 0 :(得分:7)

synchronized关键字所做的全部操作会自动阻止在对象的单个实例上多次调用synchronized方法。这意味着无论何时调用synchronized方法,都必须在任何其他同步方法可以在同一实例上执行之前退出。

但是,直接字段访问从不受到Java中任何形式的锁定的影响,因此公共字段使此类非常不安全。

答案 1 :(得分:1)

你是对的锁是对象,但这意味着只有一个线程可以在任何同步方法中。但是该字段是公共的,因此其他线程不需要在sycronized块内部。

让我们在时间T1,通过调用setX()内部的一个线程     queenInstance.setX(10);

Howwver,在同一个实例中,其他线程试图为此变量设置值: -     queenInstance.x = 12;

无法预测输出的内容。

答案 2 :(得分:0)

使setter和getter同步的唯一目的是在访问它时防止竞争条件。但由于x是公共的,任何代码都可以直接访问它,而无需使用setter或不使用getter访问它。使x public将否定Synchronized方法提供的所有安全性。