以下程序的行为是什么,静态同步方法和实例同步方法试图在不同线程中访问同一类的静态字段?任何线程都会被阻止吗?它非常令人困惑。
class MyClass
{
public static int i = 5;
public synchronized void m1()
{
System.out.println(i); //uses static field i of MyClass
//T1 is executing this method
}
public static synchronized void m3()
{
//T2 will be able to call this method on same object lock while it is using
//static field i???
System.out.println(i);//uses static field i of MyClass
}
}
答案 0 :(得分:5)
同步实例方法相当于
public void m1() {
synchronized(this) {
...
}
}
(嗯,它们并不完全相同,但你问题的答案并没有受到这种差异的影响)。
同步静态方法在类上同步:
public void m2() {
synchronized(MyClass.class) {
...
}
}
如您所见,两个块在差异对象上同步:m1
在调用它的实例上同步,m2
在Class<MyClass>
的实例上同步你在JVM中的类。因此可以调用这两种方法而不会相互阻塞。
答案 1 :(得分:4)
您始终在对象上进行同步。
Funciton m1在调用它的对象的实例上同步。
函数m3在类本身上同步。
m1可以写成:
public void m1()
{
synchronized(this) {
System.out.println(i); //uses static field i of MyClass
//T1 is executing this method
}
}
因此,您正在同步两个不同的对象,这两个方法可以同时访问任何全局变量。
答案 2 :(得分:0)
方法m1和m3可以独立执行。
因为您已经说过static synchronized
在对象上了。因此与synchronize(MyClass.class)
相同。
synchronized
可在实例范围内使用。因此它仅针对实例被阻止。它与使用相同:
MyClass myClass = new MyClass();
synchronize (myClass)
{
.....
}
答案 3 :(得分:0)
您的示例代码看起来不错。
根据我确保静态变量同步的最佳方法是。由于您的班级以外无法访问锁定对象。见下文。
public class MyClass
{
private static int i = 0;
private static final Object lockObject = new Object();
public void m1() {
synchronized (lockObject ) {
//Use you static var
}
}
public void m3() {
synchronized (lockObject ) {
//Use you static var
}
}
}
答案 4 :(得分:-1)
Java没有任何与访问静态字段相关的同步控件。
如果您的方法为空,则同步将完全相同。
具体来说,只要任何线程正在执行该类型中的任何同步静态方法,调用同步静态方法的所有其他线程将等待它们完成,因此最多只能同时执行一个同步静态方法。 / p>