jvm多线程底层执行流程分析

博客介绍了多线程执行的实现方式,对于刚开始不支持原语操作的硬件,以开关中断实现多线程执行;而支持原语操作的x86平台,CPU通过在指令执行期间对总线加锁保证指令原子性,还给出了相关汇编代码示例,此外提到Java多线程的底层执行。

内容参考: https://www.cnblogs.com/dennyzhangdd/p/6734638.html

1.对于刚开始不支持原语操作的硬件来说,多线程的执行是以开关中断来实现的。但是对于支持原语操作的硬件,比如在x86 平台上,CPU提供了在指令执行期间对总线加锁的手段。CPU芯片上有一条引线#HLOCK pin,如果汇编语言的程序中在一条指令前面加上前缀"LOCK",经过汇编以后的机器代码就使CPU在执行这条指令的时候把#HLOCK pin的电位拉低,持续到这条指令结束时放开,从而把总线锁住,这样同一总线上别的CPU就暂时不能通过总线访问内存了,保证了这条指令在多处理器环境中的原子性。

%ifdef _X_UP_
%define _X_LOCK_
%else
%define _X_LOCK_    lock
%endif

@_XPEER2_atomic_incl@4:
    mov eax , 1
    _X_LOCK_ inc DWORD [ecx+0] 
    jnz short @inclOK@
    xor eax , eax
@inclOK@:
    ret

@_XPEER2_atomic_decl@4:
    mov eax , 1
    _X_LOCK_ dec DWORD [ecx+0] 
    jnz short @declOK@
    xor eax , eax
@declOK@:
    ret    

@_XPEER2_atomic_CAS@12:
    mov eax , [esp+4]
    _X_LOCK_ cmpxchg [ecx],edx
    mov eax , 1
    jz short @CASDone@
    xor eax , eax
@CASDone@:
    ret 4

@_XPEER2_atomic_CAS2@12:
    push ebx
    push ebp    
    mov  ebp , ecx
    mov  ecx , [edx+4]
    mov  ebx , [edx+0]
    mov  edx , [esp+12]
    mov  eax , [edx+0]
    mov  edx , [edx+4]    
    _X_LOCK_ cmpxchg8b [ebp]
    mov  eax , 1
    jz short @CAS2Done@
    xor  eax , eax 
@CAS2Done@:
    pop  ebp
    pop  ebx
    ret 4    

2.下图是Java多线程的底层执行

<think>好的,我现在需要回答用户关于“线执行流程分析”的问题。用户之前已经询问过线池的实现方式,现在这个问题是关于线本身的执行流程。我需要确保回答结构清晰,符合用户提供的系统级指令,特别是使用正确的中文和LaTeX格式。 首先,我应该回顾线的基本生命周期,这是执行流程的核心部分。线的状态包括新建、就绪、运行、阻塞、等待、超时等待和终止。这些状态之间的转换需要详细说明,比如如何从新建到就绪,再到运行,以及各种阻塞的情况。 接下来,用户可能想知道线从启动到结束的具体步骤。需要解释start()方法的作用,以及为什么直接调用run()方法不会启动新线。此外,线调度器的角色也很重要,涉及时间片轮转和优先级调度,这些都会影响线执行顺序。 然后,考虑线的同步机制,比如synchronized关键字和Lock接口,以及如何避免竞态条件。这部分需要说明线在访问共享资源时可能遇到的问题,以及如何通过同步来控制执行流程。 还要包括线的中断机制,比如interrupt()方法的使用,以及如何安全地终止线。此外,线间的通信,如wait()、notify()和notifyAll()方法的作用,也是执行流程中的关键点。 需要确保回答覆盖了所有重要方面,但不过于冗长。使用示例代码时,应该用LaTeX的行内格式,比如`new Thread(() -> { ... }).start();`。同时,独立公式如状态转换图可能需要使用$$...$$,但这里可能更多是文字描述。 最后,检查是否符合用户的要求:结构清晰,逐步解释,正确使用格式,避免使用Markdown,用中文回答。可能需要将内容分成几个部分,如生命周期、执行步骤、调度、同步与通信、中断机制等,每个部分用清晰的标题和要点说明。</think>--- ### **线执行流程分析** 线执行流程涉及 **生命周期管理**、**状态切换** 和 **任务调度**,以下是关键分析点: --- #### **1. 线生命周期与状态转换** 线执行流程可通过 **6种状态**(以Java为例)描述: - **新建(NEW)**:通过 `new Thread()` 创建,尚未调用 `start()`。 - **就绪(RUNNABLE)**:调用 `start()` 后,线进入可运行状态,等待CPU调度。 - **阻塞(BLOCKED)**:竞争锁失败时(如进入 `synchronized` 代码块),线暂停执行。 - **等待(WAITING)**:调用 `wait()`、`join()` 或 `LockSupport.park()`,需其他线显式唤醒。 - **超时等待(TIMED_WAITING)**:类似等待状态,但附加超时条件(如 `sleep(ms)`、`wait(timeout)`)。 - **终止(TERMINATED)**:线执行完毕或异常退出。 **状态转换图示例**: $$ \text{NEW} \xrightarrow{\text{start()}} \text{RUNNABLE} \xrightarrow{\text{获取CPU}} \text{RUNNING} \xrightarrow{\text{任务结束}} \text{TERMINATED} $$ 其他状态通过锁竞争、I/O操作或主动调用方法触发转换。 --- #### **2. 线执行的核心步骤** 1. **创建线对象** ```java Thread thread = new Thread(() -> { /* 任务逻辑 */ }); ``` 此时线状态为 **NEW**,未分配系统资源。 2. **启动线** 调用 `thread.start()`: - JVM 创建底层系统线(如调用操作系统API)。 - 线进入 **RUNNABLE** 状态,等待CPU时间片。 3. **获取CPU时间片** - 由操作系统的线调度器分配时间片,进入 **RUNNING** 状态(Java中视为RUNNABLE的子状态)。 - 若任务未完成且时间片用完,线回到 **RUNNABLE** 等待下次调度。 4. **任务执行中状态切换** - **主动让出CPU**:调用 `Thread.yield()`,线回到就绪队列。 - **等待资源**:如执行 `synchronized` 锁竞争失败 → **BLOCKED**;调用 `sleep()` → **TIMED_WAITING**。 5. **任务结束或中断** - 正常执行完成 → **TERMINATED**。 - 被中断(调用 `thread.interrupt()`)→ 触发 `InterruptedException`,线终止。 --- #### **3. 线调度机制** - **抢占式调度**:由操作系统决定线切换(如时间片耗尽或高优先级线就绪)。 - **协作式调度**:依赖线主动释放CPU(如调用 `yield()` 或等待I/O)。 **优先级影响**(不绝对保证执行顺序): ```java thread.setPriority(Thread.MAX_PRIORITY); // 1~10,默认5 ``` --- #### **4. 同步与通信对执行流程的影响** - **同步代码块**:线进入 `synchronized` 区域时,若锁被占用 → **BLOCKED**。 - **等待/通知机制**: ```java synchronized (lock) { lock.wait(); // 释放锁,线进入WAITING lock.notify(); // 唤醒等待线 } ``` - **条件变量(Condition)**:与 `Lock` 配合使用,提供更灵活的等待/唤醒控制。 --- #### **5. 线中断机制** - **中断标志位**:调用 `thread.interrupt()` 设置中断标志。 - **响应中断**:线需周期性检查标志或捕获 `InterruptedException`: ```java while (!Thread.currentThread().isInterrupted()) { // 执行任务 } ``` --- #### **6. 典型执行场景分析** **场景1:线竞争锁** - 线A获取锁 → 执行同步代码。 - 线B尝试获取同一锁 → 进入 **BLOCKED**。 - 线A释放锁 → 线B被唤醒,竞争锁(可能再次失败)。 **场景2:I/O阻塞** - 线调用阻塞式I/O(如 `Socket.read()`)→ 进入 **WAITING** 或 **TIMED_WAITING**。 - I/O就绪后 → 线回到 **RUNNABLE**。 **场景3:线池任务执行** - 任务提交到线池 → 由空闲线或新创建线执行。 - 任务结束 → 线归还到池中,等待下一个任务。 --- **总结**:线执行流程的核心是 **状态转换** 和 **资源竞争**。理解线调度、同步机制和中断控制,是优化多线程序的关键。面试中需结合代码示例说明状态变化(如 `wait()` 与 `notify()` 的调用时机)。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值