Java中的并发:同步静态方法 [英] Concurrency in Java: synchronized static methods
问题描述
我想了解如何在Java中对静态方法进行锁定。
I want to understand how locking is done on static methods in Java.
假设我有以下类:
class Foo {
private static int bar = 0;
public static synchronized void inc() { bar++; }
public synchronized int get() { return bar; }
我的理解是当我打电话给 f.get()
,该线程获取对象 f
的锁定,当我执行 Foo.inc()
线程获取类 Foo
上的锁。
It's my understanding that when I call f.get()
, the thread acquires the lock on the object f
and when I do Foo.inc()
the thread acquires the lock on the class Foo
.
我的问题是两个呼叫如何相互同步?
调用静态方法也会获取所有实例化的锁定,或者相反(这似乎更合理)?
My question is how are the two calls synchronized in respect to each other? Is calling a static method also acquires a lock on all instantiations, or the other way around (which seems more reasonable)?
编辑:
我的问题不完全是如何静态同步
有效,但静态和非静态方法如何相互同步。
ie,我不希望两个线程同时调用 f.get()
和 Foo.inc()
,但这些方法获得了不同的锁。我的问题是这是如何可以预防的并且在上面的代码中被阻止了。
My question isn't exactly how static synchronized
works, but how does static and non-static methods are synchronized with each other.
i.e., I don't want two threads to simultaneously call both f.get()
and Foo.inc()
, but these methods acquire different locks. My question is how is this preventable and is it prevented in the above code.
推荐答案
静态和实例 synchronized
方法彼此无关,因此您需要在它们之间应用一些额外的同步,如下所示:
Static and instance synchronized
methods are not related to each other, therefore you need to apply some additional synchronization between them, like this:
class Foo {
private static int bar = 0;
public static synchronized void inc() { bar++; }
public synchronized int get() {
synchronized (Foo.class) { // Synchronizes with static synchronized methods
return bar;
}
}
}
(尽管在这种情况下离开在 get()
上 synchronized
没有意义,因为它不会做任何需要在实例上进行同步的事情) 。
(though in this case leaving synchronized
on get()
doesn't make sense, since it doesn't do anything that requires synchronization on instance).
小心死锁 - 因为这段代码需要多个锁,所以它应该按照一致的顺序执行,即其他同步的静态方法不应该尝试获取实例锁。
Beware of deadlocks - since this code aquires multiple locks, it should do it in consistent order, i.e. other synchronized static methods shouldn't try to acquire instance locks.
另请注意,使用原子字段可以在没有同步的情况下解决此特定任务:
Also note that this particular task can be solved without synchronization at all, using atomic fields:
class Foo {
private static AtomicInteger bar = new AtomicInteger(0);
public static void inc() { bar.getAndIncrement(); }
public int get() { return bar.get(); }
}
这篇关于Java中的并发:同步静态方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!