线程如何在底层执行指令?

深入理解Java线程执行机制

一条线程是如何执行的呢

一条线程它有自己独立的栈和pc寄存器,寄存器的作用来存储字节码指令地址,它来告诉电脑要执行的下一条指令。

我们通过main方法反编译出来的代码,来详细的探究main线程执行方法中代码的具体过程:

反编译出来的代码

开始执行:bipush 15

表示把15压入操作数栈中

执行 istore_1

表示把把操作数栈中的15拿出来,然后存入局部变量表1的位置

执行bipush 8 以及 istore_2 同上

都是把先把8放入操作数栈,然后拿出来存到局部变量表

执行 iload_1

表示把局部变量表中1位置的数据拿出来,放到操作数栈中

这个注意,拿出来并不会清空局部变量表1位置的数据,而是方法执行完才会清除

执行 iload_2

表示把局部变量表中2位置的数据拿出来,压到到操作数栈中

执行 iadd

表示执行+操作,然后在操作数栈中得到23

执行 istore_3

表示将操作数栈中的23拿出来,存放的局部变量表3的位置

最后执行 return

表示方法结束,销毁栈

### Linux 线程调度底层实现机制 #### 调度器架构概述 Linux 的线程调度由内核中的 CFS(完全公平调度程序)负责处理。CFS 是基于红黑树的数据结构来维护可运行的任务列表,从而确保每个任务都能获得合理的 CPU 时间片[^1]。 #### 进程与线程表示 在 Linux 中,进程和线程都作为 `task_struct` 结构体实例存在。对于多线程应用而言,主线程和其他子线程共享相同的地址空间、文件描述符表等资源,但在调度上它们各自拥有独立的 `task_struct` 实例[^2]。 #### 创建新线程时的初始化工作 当通过系统调用如 `clone()` 或者高级库函数 pthread_create() 来创建一个新的 POSIX 线程时,在内核内部会执行一系列操作来进行必要的初始化: - 分配并填充新的 task_struct; - 设置初始上下文环境; - 将其加入到当前进程所属的 cgroup 和 namespace 下; - 如果启用了 NUMA 支持,则还需考虑节点间的内存分配策略; 这些准备工作完成后,新线程就可以被放入就绪队列等待调度了[^3]。 #### 多核心上的线程分布 为了提高性能,现代计算机通常配备多个物理CPU核心甚至支持超线程技术(SMT),这使得单个处理器能够并发执行更多指令流。因此,在设计多核平台下的高效调度算法时需特别注意如何平衡各 CPU 上的工作负载以及减少跨 socket 访问带来的延迟开销等问题。 具体来说,Linux 使用了名为 "调度域"(scheduling domains, sd)的概念来组织逻辑 CPUs 形成层次化的拓扑关系图,并据此实施动态调整以优化整体吞吐量表现。每一个sd可以进一步细分为若干个"调度组"(sg), 它们共同构成了整个系统的调度框架基础。 #### 负载均衡过程 随着时间推移,某些 CPU 可能会出现过载现象而其他部分却处于闲置状态。为了避免这种情况发生进而影响用户体验,定期进行全局范围内的负载评估变得至关重要。为此目的所采取的主要措施包括但不限于: - 维护每颗 CPU 当前已占用的时间比例统计信息; - 对于那些长期维持高负荷运转的核心尝试寻找合适的候选对象转移一部分待办事项过去; - 针对不同优先级类别(比如实时 vs 普通用户态进程)分别制定专门规则指导迁移决策流程; 以上所有活动均是在后台自动完成无需应用程序开发者额外干预即可享受良好响应速度的同时保持较高的能源效率水平。 ```c // 示例代码片段展示了一个简化版的 load_balance 函数签名 static int load_balance(int this_cpu, struct rq *this_rq, struct sched_domain *sd, enum cpu_idle_type idle, struct lb_env *env); ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值