Ami*_*hum 9 java multithreading synchronized
我想了解如何在Java中对静态方法进行锁定.
假设我有以下课程:
class Foo {
private static int bar = 0;
public static synchronized void inc() { bar++; }
public synchronized int get() { return bar; }
Run Code Online (Sandbox Code Playgroud)
我的理解是,当我调用时f.get(),线程获取对象的锁定f,当我执行时Foo.inc(),线程获取类的锁定Foo.
我的问题是两个呼叫如何相互同步?调用静态方法也会获取所有实例化的锁定,或者相反(这似乎更合理)?
编辑:
我的问题并不完全是如何static synchronized工作的,但静态和非静态方法是如何相互同步的.也就是说,我不希望两个线程同时调用这两个f.get()和Foo.inc(),但这些方法获得不同的锁.我的问题是这是如何可以预防的,并且在上面的代码中是否被阻止了.
静态和实例synchronized方法彼此无关,因此您需要在它们之间应用一些额外的同步,如下所示:
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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
(尽管在这种情况下,留下synchronized的get()没有任何意义,因为它没有做任何事情需要在实例同步).
注意死锁 - 因为这段代码需要多个锁,所以它应该按照一致的顺序执行,即其他同步的静态方法不应该尝试获取实例锁.
另请注意,使用原子字段可以在不进行同步的情况下解决此特定任务:
class Foo {
private static AtomicInteger bar = new AtomicInteger(0);
public static void inc() { bar.getAndIncrement(); }
public int get() { return bar.get(); }
}
Run Code Online (Sandbox Code Playgroud)
同步静态方法实际上等效于:
public static void foo() {
synchronized (ClassName.class) {
// Body
}
}
Run Code Online (Sandbox Code Playgroud)
换句话说,它锁定Class与声明该方法的类相关联的对象.
同步方法在执行之前获取监视器(第17.1节).对于类(静态)方法,使用与方法类的Class对象关联的监视器.对于实例方法,使用与此关联的监视器(调用该方法的对象).
| 归档时间: |
|
| 查看次数: |
14948 次 |
| 最近记录: |