2

假设你有:

public class Foo {
    public Bar b;
}
public class Bar {
    public int x;
    public int y;
}

然后你打电话:

Foo f = new Foo();
....
synchronized(f) {
   f.b.x = 3;
   f.b.y = 5; //x and y must be adjacent primes at all times.
}

如果我们的线程安全性很深?即同步(f)是否会阻止另一个线程(在它自己的同步(f)块内)在更新fb时看到fb?改用 synchronized(this) 怎么样?

4

2 回答 2

6

一点也不。

synchronized关键字仅影响同一对象周围的其他同步块。
它与对象本身无关。

于 2013-09-08T19:29:24.587 回答
6

询问同步是否“深度”表明您还没有完全理解 Java 线程“同步”的工作原理。所有刚开始使用 Java 的程序员通常都有同样的误解——“同步f使对f' 字段的访问是线程安全的”。这不是真的。

当一个线程正在执行您的块时,没有其他线程可以进入同一对象上的synchronized(f)任何块或方法。就这些。synchronized

没有理由必须f通过同步 on来保护 的可变字段f。您可以根据需要在任何对象上同步,只要您始终使用相同的对象,并且只要您在访问/修改f.

相反,同步f并不意味着您对f' 字段的访问一定是线程安全的。您可以在程序的其他地方有一些其他代码,修改f's 字段而根本没有任何同步,或者在不同的对象上同步。

如果这看起来令人困惑,那是因为它是。Java 的设计者做出了一个错误的选择(将隐式互斥锁与每个对象关联),我们只需要处理它。

于 2013-09-08T19:47:01.457 回答