进程与线程

本文介绍了进程和线程的基本原理,包括进程的组成(程序段、数据段、PCB)和线程的构成(线程描述信息、程序计数器、栈内存)。通过Java实例展示了线程的ID、状态、优先级等信息的获取。强调了进程作为资源分配单位,线程作为调度单位的概念,并指出线程间的资源共享和独立性。最后,探讨了进程与线程的区别,如线程的快速切换和轻量级特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、基本原理

1.1 进程基本原理

	在了解线程之前肯定得知道进程是什么?
	一个进程一般来说由程序段、数据段和进程控制块三部分组成。
  1. 程序段:程序段一般称为代码段,进程的程序指令存放在内存中的位置,包含需要执行的指令集合。
  2. 数据段:进程操作数据在内存中的位置,包含操作的数据集合。
  3. 程序控制块:俗称(PCB)包含进程的描述信息和控制信息,是进程存在的唯一标志。

PCB主要由四大部分组成:

  • 进程的描述信:进程ID和进程名称:进程ID是唯一的代表每一个进程
    进程状态:运行、就绪、阻塞
    进程优先级:进程调度的重要依据

  • 进程的调度信息:程序的起始地址:程序的第一指令的内存地址,程序开始 执行的地址。
    通信信息:进程间通信时的消息队列。

  • 进程资源信息:内存信息:内存占用情况和内存管理所用的数据结构。
    I/O设备信息:所用的I/O设备编号及对应的数据结构。
    文件句柄:所打开的文件信息。

  • 进程上下文:执行时各种CPU寄存器的值、当前程序计数器(PC)的值以及各栈的值等, 可视为进程的环境。

进程大致结构

1.2、线程的基本原理

	线程是什么?
			线程是指“进程代码段”的一次顺序执行流程。线程是CPU调度的最小单位。
		一个进程可以有一个或者多个线程,各个线程之间共享进程内存空间、系
		统资源,进程仍然是操作系统资源分配的最小单位。
			Java程序中,每当执行一个class类时,都会启动一个JVM进程。实际上,
		在该进程中至少会启动两个线程,一个是main线程,一个是GC线程(垃圾回收)。

一个标准的线程主要由三部分组成:线程描述信息、程序计数器和栈内存。
线程的大致结构

在线程结构中,线程描述信息主要包括如下内容:

  1. 线程ID(线程标识符):线程的唯一标识,同一个进程内的不同线程的ID不会重叠。
  2. 线程名称:主要用于方便用户识别,用户可以指定线程名称(Thread中的setName方法设置),如果没有指定就会默认分配一个线程名称。
  3. 线程优先级:表示线程调度的优先级,优先级越高,获取CPU的执行机会就越大。
  4. 线程状态:表示当前线程执行状态,为新建、就绪、运行、阻塞、结束等状态。(在Java中的线程状态为新建 ->运行 -> 等待 -> 超时等待 -> 阻塞 ->销毁)
  5. 其他:例如守护线程等。(由于目前能力有限,在以后博客中介绍)
package com.like.thread;

import java.util.concurrent.TimeUnit;

/**
 * @author like
 * @date 2021年09月25日 16:29
 * @className ThreadDmo
 */
public class ThreadDmo {

    public static void main(String[] args) throws InterruptedException{
        /**
        * Thread.currentThread() 为Java.lang中的静态方法,用于获取正在执行的当前线程
        */
        
        System.out.println("当前线程名称:" + Thread.currentThread().getName());
        System.out.println("当前线程ID:" + Thread.currentThread().getId());
        System.out.println("当前线程状态:" + Thread.currentThread().getState());
        System.out.println("当前线程优先级:" + Thread.currentThread().getPriority());

        int a = 1;
        int b = 1;
        int c = a/b;
        threadTest();
        TimeUnit.MILLISECONDS.sleep(1000);
    }

    private static void threadTest(){
        int a = 1;
        int b = 1;
        int c = a/b;
        threadTest1();
    }

    private static void threadTest1(){
        int a = 1;
        int b = 1;
        int c = a/b;
    }
}

执行结果
当前线程名称:main
当前线程ID:1
当前线程状态:RUNNABLE
当前线程优先级:5

在Java执行流程中的重要单位为方法,栈内存的分配单位是“栈帧(方法帧)”,方法每次执行都需要为其分配栈帧(方法帧),栈中主要保存局部变量、方法的返回信息以及方法的一些其他信息。当线程的执行流程进入方法时,JVM就会为方法分配一个对应的栈帧压入栈内存;每当线程执行流程跳出方法时,JVM就从栈内存弹出该方法的栈帧,随后栈帧的局部变量内存空间就会被回收。

以上诉代码为例,简单介绍一下main线程的栈内存。
其中三个方法main、threadTest、threadTest1,三个方法中存在a,b,c三个局部变量。

  1. 当执行main()方法时,JVM就会为main方法分配一个栈帧,用来保存a,b,c三个局部变量。然后再将栈帧压入main()线程栈内存中,然后main()还未执行完(利用TimeUnit.MILLISECONDS.sleep(1000)使得main()进入等待状态),执行threadTest方法。
  2. 执行threadTest()方法之前JVM为其分配栈帧,保存a,b,c三个局部变量。然后将栈帧压入main()线程栈内存。
  3. 执行threadTest1()方法,跟以上流程一样。

main()方法的栈结构
三个方法的栈帧弹出过程和压入过程恰好相反,threadTest1()方法执行完成以后,其栈帧从main线程中的栈内存弹出,以此类推,直到main栈内存中没有剩余的栈帧,main线程才结束。
栈帧(方法帧)采取后进先出的模式,这也是标准的栈操作模式,存放方法栈的内存也称为栈内存。

1.3、进程和线程的区别

  1. 线程是“进程代码段”的一次顺序执行流程。一个进程由一个或多个线程组成,一个进程中至少有一个线程
  2. 线程是CPU调度的最小单位,进程是操作系统分配资源的最小单位。线程的划分尺度小于进程,使得多线程程序 并发性高。。
  3. 线程是出于高并发的调度诉求从进程内部演进而来。线程的出现充分发挥了CPU的计算能力,还弥补了进程调度过于笨重的问题。
  4. 进程之间是相互独立的,但进程内部的各个线程之间并不是完全独立。各个线程之间共享进程的方法区内存、堆内存、系统资源。
  5. 切换速度不同:线程上下文切换比进程上下文切换快得多。所以有时候线程也称为轻量级进程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值