java.lang.Class有什么用?它与静态方法同步有什么关系?

时间:2013-08-08 10:09:21

标签: java multithreading

我在java中读取静态方法同步。我在哪里阅读static methods获取java.lang.class对象的锁定。我试图理解java.lang.class的概念及其在静态方法同步中的作用,我有这些问题。

  1. 我正在阅读博客,其中说Java中的每个类都有java.lang.Class的实例,并且类的所有实例都共享此对象。 java.lang.Class的实例描述了对象的类型? java.lang.Class的作用是什么?它如何描述对象的类型?

  2. 其次,对于静态方法同步,我们需要获取java.lang.Class的监视器。这是为什么?为什么我们需要锁定java.lang.Class监视器?为什么不在我们自己的类的实例上,例如Test(我自己的自定义类)?

  3. 有人可以详细说明。我很抱歉,因为这听起来是一个非常基本的问题,但我对这个概念很陌生。

4 个答案:

答案 0 :(得分:4)

暂定解释,虽然不可否认它并不完全正确。对于任何课程C,当你这样做时:

final C c = new C();

这里涉及两个ObjectClass<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用于反射,因此已经存在。