操作系统系列之进程调度的基本过程
很多同学在学习多线程的时候经常被搞得一头雾水,分不清楚单线程多线程进程之间的关系,更别说从操作系统层面去理解它们的原理了,那么本文就通过具体的代码➕实例➕画图详解,帮助大家更加深入的理解多线程❗️
在当代面向线程设计的计算机结构中,进程是线程的容器。程序是指令、数据及其组织形式的描述,而进程是程序的执行过程。
注意:程序是描述,进程是程序的执行过程;
我们可以把程序看作是一张菜谱,而进程就是根据菜谱对食材进行加工的过程;
线程(英语:thread)是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。
我们再拿菜谱的例子来说明,一道菜从准备到制作完成,可能需要很繁琐的步骤:洗菜、切菜、热锅、准备调味等待,其中有些步骤是可以同时进行的,比如说有人洗菜,同时有人热锅,另一个人准备调味料;
进程就是一道菜的制作过程,线程就是同时参与这道菜制作的人,当然一个人也完全可以制作,但是为了减少制作时间,我们就很巧妙地想出了多线程的方法;
一个进程至少要有五个线程,一个主线程,也就是用来执行main函数的线程,其他线程用来作为辅助执行一些标记和垃圾回收的工作,也就是说制作“一道菜”,需要一个主厨和四个下手;
一个进程启动一个jvm,我们可以把jvm看作是一个服务商,我们把“菜谱”给jvm,jvm开始按照我们的要求进行制作;
Jvm、进程和线程之间的关系是什么样的呢?
首先,我们可以看一下单线程的程序是如何执行的?
如代码所示,这是一个单线程程序;
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函数;
如代码所示,这是一个多线程程序;
继承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方法中的语句;
接着执行mythread.start(),这个语句的作用是开辟一个新栈并使其独自运行,不受主栈影响;
输出结果是:
结果为什么不是一个主栈一个支栈交替输出的呢?
以上就是今天要讲的内容,本文是多线程详解系列文章之一,接下来还有两篇文章继续介绍多线程,如果大家觉得有帮助的话,不妨点个赞支持一下哦!!!