[JAVAEE]—进程和多线程的认识
文章目录
- 什么是线程
- 什么是进程
- 进程的组成
- 什么是pcb
- 进程概括
- 线程
- 线程与进程的关系
- 线程的特点
- 创建线程
- 创建线程方法
- 创建线程的第二种方法
- 对比
- 其他的方式
- 匿名内部类创建线程
- 匿名内部类创建Runable的子类
- lambda表达式创建一个线程
- 多线程的优势
什么是线程
什么是进程
首先想知道什么是线程就得先搞明白什么是进程,关于进程呢,我们说进程是系统进行资源分配的基本单位但是光知道这句话远远不够,因为我们不知道什么是资源分配,我们可以简单的将计算机理解为钱包。
那么资源就是钱包里的钱,至于进程就是我们要做的事情或者说要买的东西,比如说旅游啊买衣服啊。我们把资源(也就是钱)进行了划分,那一部分用来旅游哪一部分用来买衣服做了明确的划分,而这就是资源分配,至于买衣服啊之类的就是我们的进程。
进程的组成
进程是由自己的代码和pcb组成的我们上面说了,进程就是我们要执行的任务,那么在计算机中计算机要执行的任务其实就是我们写的程序,因此我们可以这样理解我们运行了一个程序那么这个程序在我们后台中就是一个进程了。他也正如其名字一样,进行中的程序。由此我们可以知道进程就是我们运行的代码,那么刚刚说的pcb又是什么呢?
什么是pcb
我们运行一个代码那么操作系统就要管理我们运行的程序代码怎么管理呢?那就是先描述再组织,相信大家对这句话应该不陌生吧。那么我们想要描述一个进程该怎么办?就像我们想要描述一个人我们需要把这个人的各种特点记录起来一样,描述进程也是这样把这个进程的各种特点记录下来,而这些特点用一个结构体保存下来这个结构体就是pcb,因此一个进程由什么组成呢?那就是自己的代码+pcb
进程概括
简单来讲进程的概念主要你有两点:
一:进程是一个运行中的实体每一个进程都有自己的内存空间包括堆栈啊等等
二:进程是一个执行的程序,他也需要被管理为了管理它系统中有一个用于存储其基本信息的结构体叫做PCB
线程
什么是线程呢?有了上面的概念我们就可以来讲一下线程了,如果说进程是进行资源分配的基本单位的话那么线程就是**线程是CPU独立运行和独立调度的基本单位。**有些同学可能就蒙了啊什么是cpu独立运行和独立调度呢?我们在购买电子设备的时候我们知道cpu会说他是几核几核的这些核心就是我们用来运行线程的。那么知道这些是不够的,对于初学者来说还是不知道线程到底是什么他跟进程到底有什么关系啊?那么我们现在就来解决一下这个疑惑。
线程与进程的关系
我们上面说了进程就是一个任务,我们去购物,旅游这样的一个任务,那么线程是什么呢?线程则是任务的步骤或者说是任务的分支,就像我们为了完成购物这个任务我们需要分成以下几个步骤那就是第一乘车去商场,第二挑选商品,第三付账,那么以上为了完成这个任务创建的分支就是线程,由此可见线程其实就是进程的分支.那么我们现在就知道为什么了解线程之前要了解进程了。
总结一下目前已知的知识点
线程是进程的一个分支
线程被创建出来是为了执行某个任务
线程是cpu独立运行和独立调度的基本单位.
线程的特点
通过以上的知识我们可以知道线程的哪些特点呢?
线程是轻量级的进程
线程没有独立的地址空间
线程依附于进程进程可以拥有多个线程
创建线程
通过以下的代码来感受以下线程和普通程序的区别吧
class Mytheard extends Thread{public void run(){while (true){try {sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("我是一个线程");}}
}
public class Main {public static void main(String[] args) throws InterruptedException{Thread ne=new Mytheard();ne.start();while(true){ne.sleep(1000);System.out.println("Hello world!");}}
}
运行截图如下
我们可以看到他跟普通的函数调用不一样的就是主函数和我们创建的这个是在并发执行的这个也就是其中最主要的一个区别.
创建线程方法
在这个代码中呢我们调用了一个start方法.这个方法其实就是创建一个线程并且在创建完成之后呢自动调用我们实现的run函数那么有些同学可能看不出来这到底跟我直接new一个Mythread对象调用这个run有什么区别我们再来看一下下面的代码
class Mytheard extends Thread{public void run(){while (true){try {sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("我是一个线程");}}
}
public class Main {public static void main(String[] args) throws InterruptedException{Thread ne=new Mytheard();ne.run();while(true){ne.sleep(1000);System.out.println("Hello world!");}}
}
这个代码运行起来呢我们可以发现他是只会执行一个while循环的.并不能做到并发执行,很明显这并不符合我们开发的一个目的.
那么这里面start和run的区别其实就是有没有创建一个线程.而这个方法其实只是我们开发中创建线程的一种方法
创建线程的第二种方法
实现Runable接口
Runable 呢是我们的一个接口,相信未来搞开发的肯定听过一句话叫做高内聚低耦合.而我们的大佬呢考虑到如果将任务和线程的创建绑定在一起就不符合这个高内聚低耦合的精神了为了解耦呢就创建了这样一个方式去创建线程代码如下
class MytheardRunable implements Runnable{public void run(){while (true){try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("我是一个线程");}}
}
public class Main {public static void main(String[] args) throws InterruptedException{Thread t=new Thread(new MytheardRunable());t.start();while(true){Thread.sleep(1000);System.out.println("Hello world!");}}
}
那么这个代码我们发现不同地方除了继承了这个接口之外还有就是我们new对象的时候我们的那里加上了一个参数.我们翻译以下就是创建一个线程对象,并且接下来要执行的任务是这个任务.
我们看一下Thread构造方法的源代码也可以发现这里面也确实有一个参数就是这个接口的参数.
并且我们查看这个接口内部的方法的时候也可以发现这个方法内部也只实现了一个run方法我们也只需要重写一个run方法即可.
对比
对比上面两种方法:
继承 Thread 类, 直接使用 this 就表示当前线程对象的引用.
实现 Runnable 接口, this 表示的是 MyRunnable 的引用. 需要使用 Thread.currentThread()
其他的方式
那么基础较好的同学看到上面的代码可能就会想到别的方式了那就是lamdba和匿名内部类的方式而事实上这两种方式也确实是一种不错的方式去创建线程代码如下
匿名内部类创建线程
public class Main {public static void main(String[] args) throws InterruptedException{Thread t=new Thread(){@Overridepublic void run() {while(true){try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("我是匿名内部类创建的一个线程");}}};t.start();while(true){Thread.sleep(1000);System.out.println("Hello world!");}}
}
匿名内部类创建Runable的子类
public class Main {public static void main(String[] args) throws InterruptedException{Thread t=new Thread(new Runnable() {@Overridepublic void run() {while(true){try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("我是Runable匿名内部类创建的一个线程");}}});t.start();while(true){Thread.sleep(1000);System.out.println("Hello world!");}}
}
lambda表达式创建一个线程
public class Main {public static void main(String[] args) throws InterruptedException{Thread t=new Thread(()->{while(true){try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("我是lambda表达式创建出的线程");}});t.start();while(true){Thread.sleep(1000);System.out.println("Hello world!");}}
}
多线程的优势
通过上面的例子我们知道了多线程和普通代码区别的就是可以并发执行,那么可以并发执行这就大大的提高了我们的程序运行效率,其实就像我们做事情是一样的,我们可以在做一件事情的同时去做另一个事情并且两个事情互不干扰,效率达到了很大的提升.
和爱的人一起努力.
相关文章:

[JAVAEE]—进程和多线程的认识
文章目录 什么是线程什么是进程进程的组成什么是pcb 进程概括线程线程与进程的关系线程的特点 创建线程创建线程方法创建线程的第二种方法对比 其他的方式匿名内部类创建线程匿名内部类创建Runable的子类lambda表达式创建一个线程 多线程的优势 什么是线程 什么是进程 首先想…...

sqllab第十九关通关笔记
知识点: 错误注入 最大长度为32位;如果目标长度>32时,需要利用截取函数进行分段读取referer注入 insert语句update语句 通过admin admin进行登录发现页面打印除了referer字段的信息 这应该是一个referer注入 首先进行测试一下 构造payl…...
张量维度改变总结
文章目录 一、view() 或 reshape()二、unsqueeze()三、squeeze()四、transpose()五、torch.expand_dims 一、view() 或 reshape() view() 或 reshape(): 这两个函数可以用于改变张量的形状,但保持元素总数不变。它们可以接受一个新的形状作为参数,并返回…...
C++ ezOptionParse的用法
在网上找了一下,发现并没有很多关于这个小型头文件的资料 只好自己上了 int main(int argc, const char * argv[]) {ezOptionParser opt;opt.overview "Demo of parsers features."; //概要说明,一般需要填写,简要介绍程序的作用opt.synta…...

MATLAB:一些杂例
a 2; b 5; x 0:pi/40:pi/2; %增量为pi/40 y b*exp(-a*x).*sin(b*x).*(0.012*x.^4-0.15*x.^30.075*x.^22.5*x); %点乘的意义 z y.^2; %点乘的意义 w(:,1) x; %组成w,第一列为x w(:,2) y; %组成w,第二列为y w(:,3) z; %组成w,第三列为z…...

使用OpenCV实现两张图像融合在一起
简单介绍 图像融合技术是一种结合多个不同来源或不同传感器捕获的同一场景的图像数据,以生成一幅更全面、更高质量的单一图像的过程。这种技术广泛应用于遥感、医学影像分析、计算机视觉等多个领域。常见的图像融合技术包括基于像素级、特征级和决策级的融合方法&a…...
PyTorch学习笔记之基础函数篇(十)
文章目录 6 张量操作6.1 torch.reshape()函数6.1 torch.transpose()函数6.1 torch.permute()函数6.1 torch.unsqueez()函数6.1 torch.squeeze()函数6.1 torch.cat()函数6.1 torch.stack()函数 6 张量操作 6.1 torch.reshape()函数 torch.reshape() 是 PyTorch 中的一个函数&a…...

kubernetes部署集群
kubernetes部署集群 集群部署获取镜像安装docker[集群]阿里仓库下载[集群]集群部署[集群]集群环境配置[集群]关闭系统Swap[集群]安装Kubeadm包[集群]配置启动kubelet[集群]配置master节点[master]配置使用网络插件[master]node加入集群[node]后续检查[master]测试集群 集群部署…...
软件工程师,该偿还一下技术债了
概述 在软件开发领域,有一个特殊的概念——“技术债”,它源于Ward Cunningham的一个比喻,主要用来描述那些为了短期利益而选择的快捷方式、临时解决方案或者未完成的工作,它们会在未来产生额外的技术成本。就像金融债务一样&#…...
HTML5、CSS3面试题(三)
HTML5、CSS3面试题(二) rem 适配方法如何计算 HTML 跟字号及适配方案?(必会) 通用方案 1、设置根 font-size:625%(或其它自定的值,但换算规则 1rem 不能小于 12px) 2…...

pytorch之诗词生成6--eval
先上代码: import tensorflow as tf from dataset import tokenizer import settings import utils# 加载训练好的模型 model tf.keras.models.load_model(r"E:\best_model.h5") # 随机生成一首诗 print(utils.generate_random_poetry(tokenizer, model)…...
Django自定义中间件
自定义中间件 传统方法的的五大钩子函数:(需要调用MiddlewareMixin类) process_request,请求刚到来,执行视图之前;正序 process_view,路由转发到视图,执行视图之前;正序…...

【JavaScript】JavaScript 运算符 ① ( 运算符分类 | 算术运算符 | 浮点数 的 算术运算 精度问题 )
文章目录 一、JavaScript 运算符1、运算符分类2、算术运算符3、浮点数 的 算术运算 精度问题 一、JavaScript 运算符 1、运算符分类 在 JavaScript 中 , 运算符 又称为 " 操作符 " , 可以实现 赋值 , 比较 > < , 算术运算 -*/ 等功能 , 运算符功能主要分为以下…...

掘根宝典之C++迭代器简介
简介 迭代器是一种用于遍历容器元素的对象。它提供了一种统一的访问方式,使程序员可以对容器中的元素进行逐个访问和操作,而不需要了解容器的内部实现细节。 C标准库里每个容器都定义了迭代器 迭代器的作用类似于指针,可以指向容器中的某个…...
DP-力扣 120.三角形最小路径和
给定一个三角形,找出自顶向下的最小路径和。每一步只能移动到下一行中相邻的结点上。相邻的结点: 下标与上一层结点下标相同或者等于上一层结点下标 1 的两个结点。样例: 例如,给定三角形: [ [2], [3,4], [6,5,7], [4…...
【WEEK3】学习目标及总结【SpringMVC】【中文版】
学习目标: 三周完成SpringMVC入门——第三周 感觉这周很难完成任务了,大概率还会有第四周 学习内容: 参考视频教程【狂神说Java】SpringMVC最新教程IDEA版通俗易懂数据处理JSON交互处理 学习时间及产出: 第三周 MON~FRI 2024.…...
peft模型微调--Prompt Tuning
模型微调(Model Fine-Tuning)是指在预训练模型的基础上,针对特定任务进行进一步的训练以优化模型性能的过程。预训练模型通常是在大规模数据集上通过无监督或自监督学习方法预先训练好的,具有捕捉语言或数据特征的强大能力。 PEF…...

【算法训练营】周测1
清华大学驭风计划课程链接 学堂在线 - 精品在线课程学习平台 (xuetangx.com) 如果需要答案代码可以私聊博主 有任何疑问或者问题,也欢迎私信博主,大家可以相互讨论交流哟~~ 考题11-1 题目描述 有一个初始时为空的序列,你的任务是维护这个…...
PyTorch Dataset、DataLoader长度
pytorch 可以直接对 Dataset 对象用 len() 求数据集大小,而 DataLoader 对象也可以用 len(),不过求得的是用这个 loader 在一个 epoch 能有几多 iteration,容易混淆。本文记录几种情况的对比。 from torch.utils.data import Dataset, DataL…...
动态IP和静态IP
与静态 IP 地址不同,动态 IP 地址会定期更改。让我们来分析一下: 1. IP 地址基础知识: * IP 地址是一个数字标签,用于唯一标识网络上的每个设备。 * 当设备通过网络通信时,数据会在它们之间来回传输。每个数据包都标有…...
KubeSphere 容器平台高可用:环境搭建与可视化操作指南
Linux_k8s篇 欢迎来到Linux的世界,看笔记好好学多敲多打,每个人都是大神! 题目:KubeSphere 容器平台高可用:环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...

基于FPGA的PID算法学习———实现PID比例控制算法
基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容:参考网站: PID算法控制 PID即:Proportional(比例)、Integral(积分&…...

人工智能(大型语言模型 LLMs)对不同学科的影响以及由此产生的新学习方式
今天是关于AI如何在教学中增强学生的学习体验,我把重要信息标红了。人文学科的价值被低估了 ⬇️ 转型与必要性 人工智能正在深刻地改变教育,这并非炒作,而是已经发生的巨大变革。教育机构和教育者不能忽视它,试图简单地禁止学生使…...

云原生安全实战:API网关Kong的鉴权与限流详解
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关(API Gateway) API网关是微服务架构中的核心组件,负责统一管理所有API的流量入口。它像一座…...
Python Einops库:深度学习中的张量操作革命
Einops(爱因斯坦操作库)就像给张量操作戴上了一副"语义眼镜"——让你用人类能理解的方式告诉计算机如何操作多维数组。这个基于爱因斯坦求和约定的库,用类似自然语言的表达式替代了晦涩的API调用,彻底改变了深度学习工程…...
go 里面的指针
指针 在 Go 中,指针(pointer)是一个变量的内存地址,就像 C 语言那样: a : 10 p : &a // p 是一个指向 a 的指针 fmt.Println(*p) // 输出 10,通过指针解引用• &a 表示获取变量 a 的地址 p 表示…...

spring Security对RBAC及其ABAC的支持使用
RBAC (基于角色的访问控制) RBAC (Role-Based Access Control) 是 Spring Security 中最常用的权限模型,它将权限分配给角色,再将角色分配给用户。 RBAC 核心实现 1. 数据库设计 users roles permissions ------- ------…...

PH热榜 | 2025-06-08
1. Thiings 标语:一套超过1900个免费AI生成的3D图标集合 介绍:Thiings是一个不断扩展的免费AI生成3D图标库,目前已有超过1900个图标。你可以按照主题浏览,生成自己的图标,或者下载整个图标集。所有图标都可以在个人或…...
LUA+Reids实现库存秒杀预扣减 记录流水 以及自己的思考
目录 lua脚本 记录流水 记录流水的作用 流水什么时候删除 我们在做库存扣减的时候,显示基于Lua脚本和Redis实现的预扣减 这样可以在秒杀扣减的时候保证操作的原子性和高效性 lua脚本 // ... 已有代码 ...Overridepublic InventoryResponse decrease(Inventor…...

【记录坑点问题】IDEA运行:maven-resources-production:XX: OOM: Java heap space
问题:IDEA出现maven-resources-production:operation-service: java.lang.OutOfMemoryError: Java heap space 解决方案:将编译的堆内存增加一点 位置:设置setting-》构建菜单build-》编译器Complier...