Rum*_*tov 0 java multithreading
我一直在网上寻找有关如何允许执行静态同步方法的信息.我发现静态同步方法将获得类锁.据我所知,这可以确保只允许所有现有类实例中的一个执行静态同步方法.这是真的吗?可以有两个类实例同时执行静态同步方法吗?因此,为了使其更具视觉效果,我正在添加代码示例.
public class A {
private static synchronized void m1() {
//Print something
}
private synchronized void m2() {
//Print something else
}
}
Run Code Online (Sandbox Code Playgroud)
据我所知,因为静态方法是获取类级别监视器而非静态方法正在获取对象级监视器,所以两者都可以同时从2个不同的线程执行,如下所示:
A a = new A;
a.m2();//object-level lock acquired
a.m1();//Class-level lock acquired
Run Code Online (Sandbox Code Playgroud)
但是,如果我们有3个上述类的实例,它们是否可以同时运行m1()?我认为他们不能,但我不确定.那会发生这种情况吗?
A a = new A;
A aa = new A;
A aaa = new A;
a.m1();
aa.m1();
aaa.m1();
Run Code Online (Sandbox Code Playgroud)
据我所知,这可以确保只允许所有现有类实例中的一个执行静态同步方法.
不,这意味着一个线程将能够执行该方法,并且同步锁是特定类加载器中的Class对象.
正如规范中所说:
同步方法在执行之前获取监视器(第17.1节).
对于类(静态)方法,使用与方法类的Class对象关联的监视器.
可以有两个类实例同时执行静态同步方法吗?
"类实例"是一个模糊的术语.如果你的意思是一个班级,那是无关紧要的; 这是一个static(类范围的)方法,而不是实例方法.如果你的意思是Class 对象,那么这就是我上面提到的类加载器的原因:在你有多个类加载器的异常情况下,你可以拥有多个Class对象 - 例如,类的副本(不是它的实例).如果您有多个Class对象,则每个对象都有自己的static方法副本.因此,由于在不同的对象上有两个副本同步,一个线程可以调用synchronized static其中一个的方法,而另一个线程正在调用其中synchronized static一个不同的成员.
但这是一个边缘案例.在正常情况下,这不是问题:您只有该方法的一个副本,并且它在Class对象的一个副本上同步,并且在任何给定时间只有一个线程可以执行它.