一、Java 程序基础执行流程

源代码 → javac编译 → 二进制字节码文件 → java命令运行程序操作系统会为运行中的程序创建进程,并分配专属内存空间。
  • 进程定义:正在执行的程序。

二、JVM 内存分区(进程内存空间)

  1. 虚拟机栈
  • 控制程序执行流程,每个线程拥有独立虚拟机栈;
  • 方法调用时,方法会压入栈帧,方法执行完毕自动出栈;
  • main方法程序启动后最先入栈。
  1. 堆所有线程共享,存放对象实例。
  2. 方法区所有线程共享,存放类信息、常量、静态变量等。

三、线程基础概念

  1. 线程:程序独立的执行流,是 CPU 最小调度单位。
  2. thread.start()作用:不会立刻执行线程,仅将线程放入就绪队列,等待 CPU 调度。
  3. 单线程递归示例:斐波那契数列
斐波那契数列公式
递归代码示例
执行特点:递归调用会持续将方法压入虚拟机栈,递归返回时依次出栈。

四、并发与并行

1. 并发

  • 宏观上多个任务同时执行,微观上线程交替占用 CPU;
  • 底层依靠时间片轮转调度实现;
  • 单 CPU 核心只能实现并发。

2. 并行

多个 CPU 核心同时执行不同线程,真正同一时间运行多个任务,需要多核处理器支持。

补充:上下文切换

CPU 切换执行不同线程时,需要保存 / 恢复线程运行现场,会产生额外时间开销,频繁切换会降低程序效率。

五、Java 多线程运行案例

示例代码

// 自定义线程类
public class ThreadNew extends Thread{
    private int flag;
    public ThreadNew(int flag){
        this.flag = flag;
    }
    @Override
    public void run() {
        if(flag==1){
            for (int i = 0; i<1000000;i++){
                System.out.println("线程1开始执行");
            }
        }else{
            for (int i = 0; i<1000000;i++){
                System.out.println("线程2开始执行");
            }
        }
    }
}

// 测试启动类
public class Test {
    public static void main(String args[]){
        ThreadNew t1 = new ThreadNew(1);
        ThreadNew t2 = new ThreadNew(2);
        t1.start();
        t2.start();
        System.out.println("main end");
    }
}

关键知识点

  1. start()不会直接运行线程,只是将线程加入就绪队列,由操作系统调度执行;
  2. 不共享资源时,各线程内存、执行逻辑相互独立;
  3. 无同步措施时,两个线程会交替打印输出,执行顺序随机。

六、线程安全解决方案

synchronized 同步锁

作用:解决多线程并发修改共享资源时的数据错乱问题,保证同一时间仅有一个线程执行临界区代码。
Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐