学不懂多线程?代码加实例详解帮你深入理解多线程(1)

系列文章目录

操作系统系列之进程调度的基本过程



前言

🌴 很多同学在学习多线程的时候经常被搞得一头雾水,分不清楚单线程多线程进程之间的关系,更别说从操作系统层面去理解它们的原理了,那么本文就通过具体的代码➕实例➕画图详解,帮助大家更加深入的理解多线程❗️


1. 什么是进程?

🌴 在当代面向线程设计的计算机结构中,进程是线程的容器。程序是指令、数据及其组织形式的描述,而进程是程序的执行过程

🌴 注意:程序是描述,进程是程序的执行过程;

🌴 我们可以把程序看作是一张菜谱,而进程就是根据菜谱对食材进行加工的过程;

系统中的进程
🌴 如图所示系统中有很多的进程;

2. 什么是线程?

🌴 线程(英语:thread)是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。

🌴 我们再拿菜谱的例子来说明,一道菜从准备到制作完成,可能需要很繁琐的步骤:洗菜、切菜、热锅、准备调味等待,其中有些步骤是可以同时进行的,比如说有人洗菜,同时有人热锅,另一个人准备调味料;

🌴 进程就是一道菜的制作过程,线程就是同时参与这道菜制作的人,当然一个人也完全可以制作,但是为了减少制作时间,我们就很巧妙地想出了多线程的方法;

🌴 一个进程至少要有五个线程,一个主线程,也就是用来执行main函数的线程,其他线程用来作为辅助执行一些标记和垃圾回收的工作,也就是说制作“一道菜”,需要一个主厨和四个下手;

3. 进程与线程的内存分配

🌴 一个进程启动一个jvm,我们可以把jvm看作是一个服务商,我们把“菜谱”给jvm,jvm开始按照我们的要求进行制作;

🌴 Jvm、进程和线程之间的关系是什么样的呢?

🌴 首先,我们可以看一下单线程的程序是如何执行的?

3.1 单线程的程序是如何执行的?

🌴 如代码所示,这是一个单线程程序;

public class TestDemo {
    public static void main(String[] args) {
        System.out.println("main开始执行");
        m1();
        System.out.println("main执行结束");

    }
    private static void m1(){
        System.out.println("方法一开始执行");
        m2();
        System.out.println("方法一执行结束");
    }
    private static void m2(){
        System.out.println("方法二开始执行");
        m3();
        System.out.println("方法二执行结束");
    }
    private static void m3(){
        System.out.println("方法三开始执行");
        System.out.println("方法三执行结束");
    }
}

🌴 这个单线程程序在jvm中的执行过程是什么样的呢?

🌴 首先,程序需要被执行时,会启动一个jvm,也就是上文说的,我们会把菜谱给一个服务商,让服务商帮我们做菜;
在这里插入图片描述

🌴 接着系统为jvm分配空间,jvm在内存中执行.Java文件;

🌴 main函数被加载到主栈中执行,单线程程序只在一个栈中执行,一个栈就是一个线程;

在这里插入图片描述

🌴 main函数调用m1函数;

在这里插入图片描述
🌴 m1函数调用m2函数;

在这里插入图片描述
🌴 m2函数调用m3函数;

在这里插入图片描述
🌴 m3函数执行完毕,并弹出;

在这里插入图片描述
🌴 以此类推,一直到main函数执行完毕并弹出;

在这里插入图片描述
🌴 所以最后的执行结果为:

在这里插入图片描述

3.2 多线程的程序是如何执行的?

3.2.1 继承thread类方法实现多线程

🌴 如代码所示,这是一个多线程程序;

🌴 继承thread类方法实现多线程,就是写一个继承Thread的类,然后在这个类里面重写run( );

import java.util.Random;

public class testdemo {
    public static void main(String[] args) {
        myThread mythread = new myThread();
        mythread.start();
        //mythread.run();
        for(int i=0;i<100;i++){
            System.out.println("这是一个主栈——》"+i);
        }
    }
}
class myThread extends Thread{
        @Override
        public void run(){
            for(int i=0;i<100;i++){
                System.out.println("这是一个分支栈——》"+i);
            }
        }
}

🌴 这个多线程程序在jvm中的执行过程是什么样的呢?

🌴 首先,程序需要被执行时,一开始还是只有一个主栈;

🌴 进入main方法,会逐条执行main方法中的语句;

在这里插入图片描述
🌴 首先会在堆区new一个mythread对象;

在这里插入图片描述

🌴 接着执行mythread.start(),这个语句的作用是开辟一个新栈并使其独自运行,不受主栈影响;

在这里插入图片描述
🌴 接下来主栈的代码继续向下执行,支栈代码也开始执行;

🌴 输出结果是:

在这里插入图片描述
🌴 因为两个栈是同时运行的,所以输出结果也是交叉在一起的;

🌴 结果为什么不是一个主栈一个支栈交替输出的呢?


总结

🌴 以上就是今天要讲的内容,本文是多线程详解系列文章之一,接下来还有两篇文章继续介绍多线程,如果大家觉得有帮助的话,不妨点个赞支持一下哦!!!

  • 24
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 29
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 29
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

马孔多镇长

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值