☰
javaEE 多线程1
2026/10/8 2:04:01 网站建设 项目流程

文章大纲

本文围绕进程与线程两大核心主题展开,帮助读者建立操作系统并发编程的基础认知。全文结构如下:

  • 引言:从资源调度视角引入进程与线程的基本概念,明确二者在操作系统中的定位。
  • 核心章节一:进程:讲解进程的创建方式、PCB 核心属性(pid、内存指针、文件描述表、状态、优先级、上下文、记账信息)、进程在操作系统中的生命周期状态,以及程序从硬盘加载到 CPU 执行的全过程。
  • 核心章节二:线程:说明线程与进程的关系、多任务在 CPU 上的并发与并行执行原理,并通过 Java 代码演示创建线程的三种方法、sleep 异常处理方式以及线程的随机调度机制。
  • 总结:回顾进程与线程的关键差异,梳理从进程到线程演进的核心动机,为后续深入学习并发编程打下基础。

什么是进程

进程是资源调度的基本单位

一个程序的运行叫做进程

而进程里怎么识别认识有独特的标识吗

站着操作系统角度理解进程

进程是怎么创建的

通过结构体来表述

PCB是线程的唯一标识

PCB是线程的控制块 当有很多进程时 为了方便 通过数据结构组织起来 方便管理

PCB

pid

进程的标识

内存指针

一组指针 指向里面的内容

文件描述表

进程的运行 很多时候需要和硬盘交互 硬盘由多个文件

进程运行时打开文件 每打开一个文件就会记录

进程的状态

就绪 cpu准备去执行它

堵塞 cpu没有去执行它

运行 cpu正在执行

进程的优先级

进程的先后顺序

有些进程得到的cpu资源比较多

进程的上下文

进程在cpu执行 一会失去cpu执行 过一会接着原来的进度执行

保存上下文 把cpu的值(pcb对应属性)保存到内存

恢复上下文 把内存保存的放在cpu运行

进程的记账记录信息

记录哪个进程运行的时间

哪个进程很久没有吃到cpu资源 就倾斜一点给它

进程在操作系统中的状态

1创建线程

创建pcb 通过结构体来描述属性

2销毁线程

想要销毁线程 通过数据结构找到对应的PCB来删除

3查看线程列表

遍历线程 把属性表示出来

程序在操作系统怎么执行的

一个程序在硬盘文件中有一个可执行文件.exe文件

操作系统通过一系列操作加载到内存中

创建PCB 进程属于就绪状态 等到CPU调度成可执行

cpu再在内存中读取指令

调度完之后 回到就绪状态、

阻塞的时候进程依旧存在,PCB 还在,只是不占用 CPU

进入终止态,等待内核清理 PCB,清理完成进程彻底消失。

由于创建和销毁进程是重量级的工程 需要消耗大量的资源 于是引入线程

线程

线程是资源执行的基本单位

线程的调度是由操作系统决定的 不能人为修改

一个进程包含多个线程

在同一个进程中 不同线程之间的资源是共享 不同进程之间互相独立

多个任务在cpu如何执行

过去的电脑只有一个内核 只能执行一个任务 打开一个软件 想要打开另一个必须关闭另外一个

现在 电脑是多核执行

采用分时复用 把同一份时间 分为若个小份

一个cpu来回切换多个线程叫并发执行

多个cpu在执行多个线程 叫并行执行

但是程序员在计算机内辨别不了 统一叫并发

创建线程的方法

1继承Thread类

public class thread00 extends Thread { //创建线程方法1 继承Thread 需要重写run方法 //线程的入口方法 public void run(){ System.out.println("你好"); } public static void main(String[] args) { thread00 n=new thread00(); //调用线程 n.start(); } }

2 //继承Runable 实例化对象 作为参数传递给thread

public class thread00 implements Runnable { public void run(){ System.out.println("不见"); } public static void main(String[] args) { thread00 n=new thread00(); Thread n1=new Thread(n); n1.start(); } }

3匿名内部类

public class thread00 { public static void main(String[] args) { Thread n=new Thread(()->{ System.out.println("不见"); }); n.start(); } }

sleep异常

public class thread00 extends Thread{ //为什么不能抛异常 因为Thread父类没有关于sleep的处理方式 也不能大于父类异常的处理方式 public void run(){ System.out.println("Bu"); try { Thread.sleep(1000); } catch (InterruptedException e) { throw new RuntimeException(e); } } //为什么这里可以之间抛异常 //因为 main方法内有关于sleep处理的异常 public static void main(String[] args) throws InterruptedException { thread00 n=new thread00(); Thread.sleep(1000); } }

异常的处理方式

1记录异常信息作为日志 以便后续处理

2设立报警机制

3进行重试 概率问题

睡眠 等待 sleep

让正在执行的线程 让出CPU指定时间

静态方法

public class thread00 extends Thread{ //为什么不能抛异常 因为Thread父类没有关于sleep的处理方式 也不能大于父类异常的处理方式 public void run(){ System.out.println("Bu"); try { Thread.sleep(1000); } catch (InterruptedException e) { throw new RuntimeException(e); } } //为什么这里可以之间抛异常 //因为 main方法内有关于sleep处理的异常 public static void main(String[] args) throws InterruptedException { thread00 n=new thread00(); Thread.sleep(1000); } }

线程的随机调度

调度的顺序是随机的 由操作系统的调控器决定 可设置优先级 但是对于操作系统只是参考

public class thread00 { public static void main(String[] args) throws InterruptedException { Thread n=new Thread(()->{ while (true) { System.out.println("1000"); try { Thread.sleep(1000); } catch (InterruptedException e) { throw new RuntimeException(e); } } }); n.start(); while (true) { System.out.println("20000"); Thread.sleep(1000); } } }

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询