一个方法为什么可以被同时调用

当一个类被Spring管理并标注为@Component时,默认情况下它是一个单例(singleton),这意味着在整个应用生命周期中,Spring只会创建一个实例,尽管只有一个实例,但该实例的方法可以被多个线程同时调用。

如果你觉得这个问题很弱智,那么,你认为的…是对的。

一、线程的和共享的

首先,了解是什么是共享的,方法栈帧是线程的,方法代码也就是程序代码段是共享的。

方法栈帧:

  • 每个线程都有自己的执行栈(stack)。
  • 当一个线程调用一个方法时,会在自己的栈上创建一个新的栈帧(stack frame)来保存方法的局部变量、参数和返回地址等信息。
  • 不同线程的栈帧是相互独立的。

方法代码:

  • 方法的代码本身是存储在程序的代码段(code segment)中,这是共享的。
  • 不同线程调用同一个方法时,它们共享相同的代码段,但每个线程有自己的栈帧。


二、方法栈帧和方法代码在哪

方法栈帧存储在栈中,方法代码也就是代码段,存储在方法区里

方法调用的内存布局

方法区(Method Area):

  • 存储类的信息、常量、静态变量、即时编译后的代码等
  • 代码段(Code Segment):
    • 存储方法的指令代码。
    • 这部分代码是共享的,所有线程都访问同一段代码。

栈(Stack):

  • 线程私有,每个线程有自己的栈。
  • 栈中保存方法的局部变量、参数、返回地址等信息。

堆(Heap):

  • 用于动态分配的对象存储。
  • 共享或私有的对象都可以存储在这里。



三、代码段为什么可以共享

只读属性:

  • 代码段通常被标记为只读(read-only),这意味着任何线程都不能修改其中的内容。
  • 由于代码段是不可变的,因此多个线程可以安全地共享同一段代码。

指令序列:

  • 代码段包含的是指令序列,这些指令定义了程序的行为。
  • 每个线程在执行这些指令时,实际上是按照顺序读取并执行指令,而不是修改它们。

CPU 指令执行:

  • CPU 在执行指令时,是从内存中读取指令并执行。
  • 由于指令是只读的,多个线程可以同时从同一位置读取指令,而不会影响彼此。

内存管理:

  • 操作系统负责管理进程和线程的内存。
  • 它会确保每个线程有自己的执行上下文(例如栈和寄存器状态),但可以让它们共享相同的代码段。



四、同一时间,大量调用同一个方法会导致性能问题

  • 高并发调用会导致频繁的上下文切换。每次上下文切换都需要保存和恢复线程状态,这会消耗额外的时间
  • 每个线程在调用方法时都会创建栈帧。如果调用次数过多,可能会耗尽栈空间,导致栈溢出
  • 即使是并发执行,CPU 的处理能力仍然是有限的。如果线程数量超过 CPU 核心数,多余的线程只能等待调度,进一步增加延迟
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值