java - 当我们使用类实例调用静态方法/函数时会发生什么?

标签 java multithreading static synchronization

静态变量和方法属于类而不是实例(对象)。通常使用 className.staticMethod()className.staticVariable 访问它们,但我们也可以使用类实例访问或调用它们,例如classInstance.staticMethod()classInstance.staticVariable

我的第一个问题是

为什么一开始就允许通过类实例访问静态方法/函数? 它有任何用例吗?

下一个问题如下。考虑下面的类

public class Counter{
private static int count = 0;

public static synchronized int getCount()
{
  return count;
}

public synchronized setCount(int count)
{
   this.count = count;
}

}

在多线程环境中,如果这些函数如下调用

Counter myCounter = new Counter();
myCounter.setCount(10);
System.out.println(myCounter.getCount());

第二个问题是

这两个函数会有单独的锁还是同一个锁(考虑到它们都是 由 myCounter 对象调用)?如果线程处理静态方法仍然获取 类级锁它如何在内部确定它必须采用什么锁?

最佳答案

问题 1: 类实例总是包含类的信息,因此从实例调用静态方法是有效的,因为它包含有关类的信息。 反过来是不可能的,因为类不会有关于它的实例的信息,所以你不能使用类名调用实例级方法。

如果您尝试通过实例调用静态方法,您将收到警告,因为您应该避免它,因此您不会得到有效的案例,但是允许通过实例进行静态调用是合乎逻辑的。

问题2: 来到第二个问题,线程进入静态 block 或方法时,jvm 知道要采用哪个锁,即类级别。用户无法控制它。因此实例方法将采用对象锁,而静态方法将采用类锁,因为线程在其上工作,而不管调用是如何进行的。

关于java - 当我们使用类实例调用静态方法/函数时会发生什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17007019/

相关文章:

c++ - 与 gnu g++ 链接静态库,没有这样的文件或目录

java - 将数据插入到通过 Java 动态更改的 MySql 表中

java - Kafka Streams 应用程序死亡,错误代码为 "StreamsException: Could not create internal topics."

java - out.write 不需要数据类型双值(Java Servlet)

java - 让一个组的每个类都有自己的 Log4j2 日志环境

multithreading - 是否有必要在Delphi中对 bool 属性进行多线程保护?

java - 使用 SwingWorker 在 GUI 中添加进度条

java - 如何反序列化 OpenNLP 训练的模型?

php - 什么时候在 PHP 中使用静态方法/字段?

java - 如何避免将此方法和所有其他变量设为静态?