标题很难制定,所以如果有人能说得更简洁,我会很高兴。
我知道方法调用在Java中是如何工作的。基本上,JVM拥有一个查找表,用于查找特定方法,然后调用它。
假设我们有一个MyClass类型的实例列表,我们通过调用i.E来处理这些实例。每个实例上都有toString()。在同一时刻会有多个线程调用toString()。所有都指向方法堆栈中的相同toString()。
所以我的问题是:JVM内部是否有一些内部同步来处理这个问题?或者每个对象都有自己的内联方法吗?
我找不到任何关于此的详细信息。 Oracle Docs的水平太高了。指针将受到高度赞赏。
由于
答案 0 :(得分:2)
数据是同步的,而不是代码(方法)。
每个线程都有自己的stack,其中存储了调用方法链的局部变量和返回地址。当程序遇到方法调用时,返回点的地址(方法调用完成时执行的指令)存储在线程堆栈中,程序流跳转到新方法(执行该方法的指令)。
可以有许多线程执行相同的代码(位于内存中的同一组指令),但每个线程都有自己的堆栈。
答案 1 :(得分:2)
我知道方法调用在Java中是如何工作的。基本上,JVM拥有一个查找表,用于查找特定方法,然后调用它。
正确。
假设我们有一个MyClass类型的实例列表,我们通过调用i.E来处理这些实例。每个实例上都有toString()。在同一时刻会有多个线程调用toString()。所有都指向方法堆栈中的相同toString()。
正确。
所以我的问题是:JVM内部是否有一些内部同步来处理这个问题?
没有。为什么?代码是只读的:它不需要顺序访问。
或者每个对象都有自己的内联方法吗?
没有。为什么需要呢?
答案 2 :(得分:0)
获得更多技术但是......
基本上,JVM拥有一个查找表,用于查找特定方法,然后调用它。
确实如此,但它可以通过传递使用这种查找表的需要来内联方法的多个实现。
在同一时刻会有多个线程调用toString()。所有都指向方法堆栈中的相同toString()。
虽然代码在概念上是只读的,但它实际上是分阶段编译和重新编译的,也可能是反编译的。每次发生这种情况时代码实际上都发生了变化它做同样的事情,但方式不同。什么是在运行时将引用交换为代码,这可能意味着不同的线程可以在一段时间内运行相同方法的不同版本。
所以我的问题是:JVM内部是否有一些内部同步来处理这个问题?
它不使用JVM可见锁,我怀疑它根本不使用互斥锁样式锁,而是使用线程安全操作来交换应该调用的方法。
或者每个对象都有自己的内联方法吗?
对象有数据,而不是方法。 Object引用了一个引用方法的类。这些引用可以在应用程序的生命周期内发生变化。