首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >java.lang.Class的用途是什么?它与静态方法同步的关系如何?

java.lang.Class的用途是什么?它与静态方法同步的关系如何?
EN

Stack Overflow用户
提问于 2013-08-08 10:09:20
回答 4查看 675关注 0票数 5

我正在阅读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(我自己的自定义类)?

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

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2013-08-08 10:24:41

试探性的解释,虽然不可否认是不完全正确的。对于任何类C,当您这样做时:

代码语言:javascript
运行
复制
final C c = new C();

这里涉及两个ObjectClass<C>对象(通过上下文类加载器提供)和c实例。c将通过它的.getClass()方法(在Object中定义)知道它是哪个类。

new关键字能够建立到正确Class的“反向链接”这一事实是JVM实现的责任。虽然JLS中肯定提到了这一点,但我不知道在哪里.

现在,更重要的是。

如果有一个方法声明为:

代码语言:javascript
运行
复制
synchronized void whatever() { someCode(); }

然后,它大致相当于(原因大致:见下文):

代码语言:javascript
运行
复制
void whatever()
{
    synchronized(this) {
        someCode();
    }
}

也就是说,此代码在实例级别上是同步的。

但是,如果方法是静态的,则如下所示:

代码语言:javascript
运行
复制
public static synchronized void meh() { someOtherCode(); }

大致相当于(为什么大致:见下文):

代码语言:javascript
运行
复制
public static void meh()
{
    synchronized(getClass()) {
        someOtherCode();
    }
}

需要注意的一点是,所有Class对象都是单例;不管您创建了多少类C的实例,.getClass()总是返回相同的Class对象。试试这个:

代码语言:javascript
运行
复制
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将对它有发言权,并将最终优化代码路径。

票数 4
EN

Stack Overflow用户

发布于 2013-08-08 10:23:59

java中的每个对象都是某个类的实例。此外,每个类也是一个对象,因此它也是某个类的实例。

java.lang.Class实例描述对象的类型?

不完全同意。java.lang.Class是一个类实例。

java.lang.Class在这里扮演什么角色?它如何描述对象的类型?

它描述所有类型的类型。

其次,对于静态方法同步,需要对java.lang.Class进行监控。为什么会这样呢?为什么我们需要它的实例锁而不是我们的类锁?

您需要对某个对象进行同步。根据定义,静态方法无法访问this,因此只剩下一个类,其中定义了

票数 1
EN

Stack Overflow用户

发布于 2013-08-08 10:45:59

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

同步静态方法有两种方法。其中之一是:

代码语言:javascript
运行
复制
static synchronized void methodName(){}

在这种情况下,用户不需要关心外部获取锁。在内部,这个类的所有静态方法(标记为同步)都需要获取其java.lang.class实例的锁。在这种情况下,非常明显的是,由于方法是静态的,因此无法在这里获取实例(new())锁,而且没有类的实例也可以存在静态方法。另外,静态方法由该类的所有对象共享。所以这个类的实例是没有问题的。

其他方法是在静态方法中使用同步块:

代码语言:javascript
运行
复制
    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()){ } 
       }

代码语言:javascript
运行
复制
static OtherClass lock = new OtherClass();
       static void methodName() {

             synchronized(lock){ // instance of other class can be used a well
             // method defination
             }
    }
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18123275

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档