我在java中读取静态方法同步。我在哪里阅读static methods
获取java.lang.class
对象的锁定。我试图理解java.lang.class
的概念及其在静态方法同步中的作用,我有这些问题。
我正在阅读博客,其中说Java中的每个类都有java.lang.Class
的实例,并且类的所有实例都共享此对象。 java.lang.Class的实例描述了对象的类型? java.lang.Class的作用是什么?它如何描述对象的类型?
其次,对于静态方法同步,我们需要获取java.lang.Class的监视器。这是为什么?为什么我们需要锁定java.lang.Class监视器?为什么不在我们自己的类的实例上,例如Test(我自己的自定义类)?
有人可以详细说明。我很抱歉,因为这听起来是一个非常基本的问题,但我对这个概念很陌生。
答案 0 :(得分:4)
暂定解释,虽然不可否认它并不完全正确。对于任何课程C
,当你这样做时:
final C c = new C();
这里涉及两个Object
:Class<C>
对象(通过上下文类加载器提供)和c
实例。 c
将通过.getClass()
方法(在Object
中定义)知道它是哪个类。
new
关键字能够与正确的Class
建立“反向链接”这一事实是JVM实施的责任。虽然在JLS中肯定会提到这一点,但我不知道在哪里......
现在,更重要的是。
如果您将方法声明为:
synchronized void whatever() { someCode(); }
然后它大致相当于(为什么粗略:见下文):
void whatever()
{
synchronized(this) {
someCode();
}
}
也就是说,此代码在实例级别同步。
如果方法是静态的,那么:
public static synchronized void meh() { someOtherCode(); }
大致相当于(为什么粗略:见下文):
public static void meh()
{
synchronized(getClass()) {
someOtherCode();
}
}
有一点需要注意的是,所有Class
个对象都是单身;无论您创建了多少个类C
,.getClass()
都会返回相同的Class
对象。试试这个:
public static void main(final String... args)
{
final String s1 = "foo";
final String s2 = "bar";
System.out.println(s1.getClass() == s2.getClass()); // true
}
添加getClass()
等同于this.getClass()
的事实,您就可以了解情况。 Class
本身是Object
,它遵守任何Object
的监控规则。
因为在这里我们总是引用完全相同的对象,监视器规则适用;)
现在,“粗略地”:在上面写的代码中,逻辑是相同的;但是,根据您编写代码的方式,字节码可能会有所不同;但是JIT会对它有发言权并最终优化代码路径。
答案 1 :(得分:1)
java中的每个对象都是某些类的实例。除此之外,每个类也是对象,因此它也是某些类的实例。< / p>
java.lang.Class的实例描述了对象的类型?
不完全是。 java.lang.Class
是类实例的类。
java.lang.Class的作用是什么?它如何描述对象的类型?
它描述了所有类型的类型。
其次,对于静态方法同步,我们需要获取java.lang.Class的监视器。这是为什么?为什么我们需要它的实例锁而不是我们的类锁?
您需要在某个对象上进行同步。根据定义,静态方法无法访问this
,因此剩下的唯一共享内容是类,其中定义了。
答案 2 :(得分:1)
其次,对于静态方法同步,我们需要获取监视器 java.lang.Class。这是为什么?为什么我们需要锁定 java.lang.Class监视器?为什么不在我们自己的类的实例上呢 示例测试(我自己的自定义类)?
有两种方法可以同步静态方法。一个是这个:
static synchronized void methodName(){}
在这种情况下,用户无需关心从外部获取锁定。在内部,此类的所有静态方法(标记为 synchronized )都需要获取对其java.lang.class实例的锁定。在这种情况下非常明显的是,由于方法是静态的,因此无法获取实例(新的Class())锁,并且静态方法可以在没有类的实例的情况下存在。此类的所有对象也共享静态方法。所以这个类的实例是不可能的。
其他方法是在静态方法中使用synchronized块:
static void methodName() {
synchronized(ClassName.class){ // same as above approach
// method defination
}
synchronized(this){ } // not allowed. compile time error
// to get lock of instance of this class you do as shown below. But it is not useful at all. Because every time u acquire different instance. So synchronization is not achieved.
synchronized(new Class()){ }
}
OR
static OtherClass lock = new OtherClass();
static void methodName() {
synchronized(lock){ // instance of other class can be used a well
// method defination
}
}
答案 3 :(得分:0)
班级java.lang.Class
是您班级的代表。类Class
的主要用途是使用反射(例如获取构造函数和方法)。
为此,将其视为元对象......一个类的所有实例共享此元对象。
java的设计者选择了监视器必须处理对象。要在静态方法上使用监视器,必须使用前面提到的元对象(或类)。
我认为这使得同步块的监视器的设计和实现更容易。另外,如上所述,类java.lang.Class
用于反射,因此已经存在。