当前位置:  开发笔记 > 编程语言 > 正文

Java同步静态方法:锁定对象或类

如何解决《Java同步静态方法:锁定对象或类》经验,为你挑选了4个好方法。

Java教程说:"同一个对象上的两个同步方法的调用不可能交错."

这对静态方法意味着什么?由于静态方法没有关联对象,所以synchronized关键字会锁定类,而不是对象吗?



1> Cowan..:

只是为了给Oscar添加一些细节(令人愉悦的简洁!)答案,Java语言规范的相关部分是8.4.3.6,'synchronized Methods':

同步方法在执行之前获取监视器(第17.1节).对于类(静态)方法,使用与方法类的Class对象关联的监视器.对于实例方法,使用与此关联的监视器(调用该方法的对象).


有用,我正在寻找那个引用+1

2> OscarRyz..:

由于静态方法没有关联对象, 所以synchronized关键字会锁定类,而不是对象吗?

是.:)


请回答详细说明,以便每个人都能理解.
@vemv嗯,是的,要理解答案,你必须先阅读这个问题.
@Madhu.这意味着如果在同一个类上有2个或更多同步方法,则两个都不能同时执行,即使该类有多个实例也是如此.锁定与每个同步方法的Object.class上的锁定基本相同.

3> jfpoilpret..:

您需要注意的一点(几个程序员通常属于该陷阱)是同步静态方法和同步非静态方法之间没有链接,即:

class A {
    static synchronized f() {...}
    synchronized g() {...}
}

主要:

A a = new A();

线程1:

A.f();

线程2:

a.g();

f()和g()不相互同步,因此可以完全同时执行.


是的,你的非静态方法必须在类本身上显式同步(即`synchronized(MyClass.class){...}`.
但是如果g()正在改变f()正在读取的一些静态变量呢?我们如何使该线程安全?那么我们是否明确获得了对该类的锁定?

4> 小智..:

除非你按如下方式实现g():

g() {
    synchronized(getClass()) {
        ...
    }
}

当我想在对象的不同实例之间实现互斥时(例如,在访问外部资源时需要),我发现这种模式也很有用.


请注意,这里可能存在一些非常微妙和令人讨厌的错误.记得`getClass()`返回_runtime_类型; 如果您对类进​​行子类化,那么父类和子类将在不同的锁上进行同步.如果你需要确保所有实例都使用相同的锁,那么`synchronized(MyClass.class)`就是你的选择.
推荐阅读
惬听风吟jyy_802
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有