有人能让我理解以下两个功能之间的根本区别:
public static void synchronized f() {… }
和
public void synchronized f() {… }
答案 0 :(得分:12)
在
的情况下public void synchronized f(){...}
同步是封闭类的每个实例。这意味着多个线程可以在类的不同实例上调用f
。
对于
public static void synchronized f(){...}
无论封闭类的实例数是多少,一次只能有一个线程调用该方法。
从技术上讲,第一个示例中synchronized
占用的监视器是对象实例的监视器,第二个示例中的监视器是Class
对象的监视器。
请注意,如果您在不同的ClassLoaders
中使用相同名称的类,则不要共享同一个监视器,但这是您不太可能遇到的详细信息。< / p>
答案 1 :(得分:2)
在“静态同步”方法中,同步的锁在类本身上;在“同步”方法中,锁定在对象上。请注意,这意味着“静态同步”方法不会被正在运行的“同步”方法阻止,反之亦然。有关详细信息,请参阅:http://geekexplains.blogspot.com/2008/07/synchronization-of-static-and-instance.html
答案 2 :(得分:1)
我想:
public void synchronized f() {… }
同步对象本身(this
)
public static void synchronized f() {… }
在对象的Class
个实例上进行同步(object.getClass()
或SomeClass.getClass
)
我错了
答案 3 :(得分:0)
假设方法f在类Foo中。静态版本将锁定类级别的静态方法调用(getClass()或Foo.class返回的对象)。非静态版本将锁定该类的特定实例,因此请说:
Foo x = new Foo();
Foo y = new Foo();
// Locks method f of instance x, but NOT for y.
x.f();
在静态实例中,对f()的调用将锁定两个版本,因此一次只能对f执行一次方法调用。