目录
什么是线程?
线程的创建和上下文切换:
线程的入栈和出栈:
堆栈的作用:
CPU核心数概念
线程的start状态
就绪队列
操作系统的时间片
线程中代码执行顺序
实际中内存图
什么是线程?
-
线程的创建和上下文切换:
- 创建线程:线程的创建是通过调用操作系统提供的线程创建函数或类似机制来完成的。当创建一个线程时,操作系统会为它分配独立的堆栈内存区域,并为其设置一个唯一的标识符。同时,该线程也会共享进程的其他资源,如内存、文件描述符等。
- 上下文切换:在多线程环境下,操作系统会根据一定的调度策略来决定使用哪个线程执行,这个过程称为上下文切换。上下文切换涉及到将当前线程的上下文(包括程序计数器、寄存器值等)保存起来,然后恢复切换到的线程的上下文。
-
线程的入栈和出栈:
- 入栈过程:当线程被调度执行时,它的执行流会从当前程序指令流入栈,即将当前执行点(例如程序计数器)推入线程的堆栈中。这样可以保留当前执行点,以便在上下文切换后能够恢复到正确的执行点。
- 出栈过程:当一个线程的执行结束或被调度让出执行权时,它的执行流会从堆栈中弹出,即将保存的执行点弹出,恢复到之前的执行点,并在适当的位置继续执行。
-
堆栈的作用:
- 堆栈的主要作用是存储线程执行过程中的局部变量、函数调用信息以及控制流相关的上下文信息。每个线程都有自己的堆栈,以保证线程之间的数据隔离和独立性。
- 堆栈还用于存储函数调用的参数和返回地址,在函数调用时,参数会被压入堆栈,函数执行完毕后,根据返回地址可以将控制流返回到调用者的正确位置。
CPU核心数概念
CPU的核心某一时刻只能够执行一个任务
如果有多个线程的话 ,他们就会立刻去抢占cpu
-
并行执行:如果CPU拥有多个核心,每个核心都可以并行执行不同的任务。这意味着在具有多个核心的系统中,多个线程可以同时运行在不同的核心上,从而实现并行计算和执行多个任务。
-
进程和线程的调度:当有多个线程需要执行时,操作系统的调度器会根据一定的策略将线程分配到不同的核心上运行。调度器通常基于一些算法,如时间片轮转或优先级来确定哪个线程被调度到哪个核心上。这样可以实现多个线程的并发执行。
-
线程抢占:当多个线程同时竞争同一个核心时,操作系统可以通过线程调度机制来实现线程的抢占。线程抢占是指当一个线程占用了核心时,如果拥有更高优先级的线程需要执行,操作系统可以暂停当前线程的执行,并切换到更高优先级的线程去执行。这种方式可以实现对CPU资源的公平分配,确保高优先级的任务能够及时执行。
线程的start状态
.start()只是让线程进入就绪态,然后交由操作系统去管理,它会先放入就绪队列,然后操作系统进行选择去执行
就绪队列
任何预言中的线程都只是提交到操作系统中的就绪队列,不可能让他立刻执行
操作系统中的就绪队列并不是一个先进先出的队列,也就是说先进入就绪态的方法不一定先被执行
操作系统的时间片
就绪队列中的任务被选中的时候,,操作系统就会同时分配一个执行时间,如果在时间内没有执行完,就保留当前状态并去执行其他线程,不会让一个线程一直霸占着资源
这也就导致了 先就绪的线程但不一定是先执行完的
线程中代码执行顺序
同一个线程中肯定是从上向下开始执行的
不同的线程中,代码执行顺序是不一样的
实际中内存图
public class Person {
public void m1(){}
public void m2(){
m3();
}
public void m3(){}
}
public class Test {
public static void main(String[] args) throws Exception{
// TODO Auto-generated method stub
Thread x1 = new Thread() {
@Override
public void run() {
Person w1 = new Person();
w1.m2();
}
};
Thread x2 = new Thread() {
@Override
public void run() {
Person w1 = new Person();
w1.m3();
}
};
///=====
x1.start();
x2.start();
Person w1 = new Person();
w1.m1();
}
当Test运行的时候,内存中是这样子的