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

系列文章目录

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


文章目录

  • 系列文章目录
  • 前言
  • 1. 什么是进程?
  • 2. 什么是线程?
  • 3. 进程与线程的内存分配
    • 3.1 单线程的程序是如何执行的?
    • 3.2 多线程的程序是如何执行的?
      • 3.2.1 继承thread类方法实现多线程
  • 总结


前言

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


1. 什么是进程?

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

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

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

学不懂多线程?代码加实例详解帮你深入理解多线程(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,也就是上文说的,我们会把菜谱给一个服务商,让服务商帮我们做菜;
学不懂多线程?代码加实例详解帮你深入理解多线程(1)_第2张图片

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

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

学不懂多线程?代码加实例详解帮你深入理解多线程(1)_第3张图片

main函数调用m1函数;

学不懂多线程?代码加实例详解帮你深入理解多线程(1)_第4张图片
m1函数调用m2函数;

学不懂多线程?代码加实例详解帮你深入理解多线程(1)_第5张图片
m2函数调用m3函数;

学不懂多线程?代码加实例详解帮你深入理解多线程(1)_第6张图片
m3函数执行完毕,并弹出;

学不懂多线程?代码加实例详解帮你深入理解多线程(1)_第7张图片
以此类推,一直到main函数执行完毕并弹出;

学不懂多线程?代码加实例详解帮你深入理解多线程(1)_第8张图片
所以最后的执行结果为:

学不懂多线程?代码加实例详解帮你深入理解多线程(1)_第9张图片

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方法中的语句;

学不懂多线程?代码加实例详解帮你深入理解多线程(1)_第10张图片
首先会在堆区new一个mythread对象;

学不懂多线程?代码加实例详解帮你深入理解多线程(1)_第11张图片

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

学不懂多线程?代码加实例详解帮你深入理解多线程(1)_第12张图片
接下来主栈的代码继续向下执行,支栈代码也开始执行;

输出结果是:

学不懂多线程?代码加实例详解帮你深入理解多线程(1)_第13张图片
因为两个栈是同时运行的,所以输出结果也是交叉在一起的;

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


总结

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

你可能感兴趣的:(操作系统,java,开发语言,系统架构,windows,linux)