当前位置: 首页 > news >正文

【JavaEE】初识线程


一、简述进程

认识线程之前我们应该去学习一下“进程" 的概念,我们可以把一个运行起来的程序称之为进程,进程的调度,进程的管理是由我们的操作系统来管理的,创建一个进程,操作系统会为每一个进程创建一个 PCB,并为进程在内存中开辟一块运行空间 ,然后把这个 PCB 加入到链表中。

进程的调度是为了解决,处理多进程运行的机制,CPU 按照并发的方式执行进程,在进程之间高速切换,看起来就是多进程同时运行。为了描述控制进程的运行,系统中存放进程的管理和控制信息的数据结构称为进程控制块(PCB Process Control Block),它是进程实体的一部分,是操作系统中最重要的记录性数据结构。它是进程管理和控制的最重要的数据结构,每一个进程均有一个PCB,PCB 记载了进程的优先级,进程的状态,进程的上下文,进程的记账信息等等。

进程的概念就是为了能够实现,多任务,并发执行(”同时执行“)的机制。

能否实现多进程并发执行,需要看操作系统是否能够支持操作,执行的效率这个是考验CPU 的性能。

想要学习更多进程知识的朋友可以观看博主的上一篇博客——【JavaEE】浅识进程_保护小周ღ的博客


二、什么是线程

进程是操作系统分配资源的基本单位,无论是创建,还是调度都是非常麻烦的,进程与进程之间的独立性是较高的,多进程协同维护同一个程序,对资源的消耗是非常大的。

举个例子:我们的QQ 当我们与别人打qq电话的时候,还可以接收qq 消息,并且qq空间同一时刻也接收了你铁哥们发的动态,做个假设,这三个功能是不是可以看作是三个进程,他们可以相互独立的运行,不受其他进程的影响,进程之间又有着某种关联,可以相互通信,他们共同维护了 qq 这个应用。

那么这个假设的例子:我们运行qq , 操作系统此时要给三个进程分配系统资源,开辟内存空间,而且还要花费精力保证进程之间的通信、关联性,是不是很复杂~此时的复杂主要体现在系统资源的分配上。


2.1 线程的概念

线程是建立在进程的基础之上的,可以看作是轻量级的进程,一个进程可以包含一个或者多个线程,同一个进程下的线程之间都是独立且可以调度执行的“执行流”,也是并发执行的,这些线程之间共用父进程的系统资源。

举个例子:


根据以上实例:

  1. 线程是建立在进程的基础上的,进程包含线程

  1. 同一个进程内部,多个线程之间,共用一份系统提供给进程的资源(内存空间,资源共享)

  1. 启动进程后(一般是会创建一个线程,例如 JAVA ,C/C++ 中的main() 函数,程序从main()函数开始执行,操作系统为main() 函数开辟栈帧,然后CPU 的寄存器处理、维护栈帧),需要系统花时间,花精力去分配系统资源,进程创建完毕后,无论当中有多少个线程,站在进程的角度上都不需要再去申请系统资源了,线程之间共用一份进程资源。

  1. 进程是系统分配资源的基本单位。

  1. 操作系统真正调度的是线程,线程是操作系统调度运行的基本单位。

  1. 进程之间相互独立,同一个进程之下,线程之间共享进程资源,此时如果其中一个线程崩溃有可能会对其他线程造成影响,甚至是崩溃。

  1. 一个进程中的线程数应当设计合理,线程之间也是并发执行,而CPU 的核心处理器是有限的,如果同一个进程下的线程过多,虽然在系统资源的分配上只需要执行一次,但是 CPU 需要并发处理的数量过多的话,反而会使得线程的执行的效率变低(CPU高速来回切换的处理线程)。

上文博主假设的qq 例子,应该是一个进程,然后不同的功能交由多线程来执行,功能之间可以独立并发执行,共同维护我们的qq。


三、 Java创建线程

Java 学习过程中主要是偏向于多线程开发,那么接下来学习的是如何用Java 代码来创建一个线程。

3.1 继承Thread 类

Java 标准库中 Thread 类可以视为是对操作系统提供的 API 进行了进一步的抽象和封装.

API : Application Programing linerface

给你一个软件,你能对他干什么,基于它提供的这些功能,就可以写一些代码,然后封装在一起,方便别人使用。

举个例子:

张三肚子饿了,想吃猪脚饭,自己做吧,首先得买猪脚,买调料,洗猪脚,切割,起锅烧油……想想都麻烦,于是张三打消了自己做饭的念头,于是前往楼下小吃店购买猪脚饭,张三到店之后,老板娘给张三一张纸,让他写一写自己想吃啥。

什么意思?我们想吃猪脚饭,不需要知道猪脚饭是怎么做的,我们只需要知道哪里有卖猪脚饭得地方即可

我们想创建一个线程,首先得找到 ”饭店“,这个饭店就是操作系统对创造线程操作封装的API ,然后JAVA 把 操作系统提供的 API 进一步的处理,封装成 Thread 类,我们不需要知道 系统是怎么创建一个线程的,只需要知道 Thread 类,可以吃到 "猪脚饭”。

代码实现:

class MyThread extends Thread {// MyThread 类继承 Thread 类,创建一个线程类// 并重写 Thread 类的 run() 方法// 此时MyThread 线程类的 run() 方法相当于 主线程中的 main() 方法@Overridepublic void run() {while (true) {try {Thread.sleep(1000); //线程休眠,1000 = 1 秒System.out.println("t 线程 执行");} catch (InterruptedException e) {e.printStackTrace();}}}
}public class Demo1 {public static void main(String[] args) {// 创建 MyThread 线程类实例化对象Thread t = new MyThread();// start 创建是新的线程并启动执行,调用run() 方法// 创建线程默认就会执行线程的 run 方法// 不调用 start() 方法线程不会启动t.start();while (true) {try {Thread.sleep(1000); //线程休眠,1000 = 1 秒System.out.println("Main主线程 执行");} catch (InterruptedException e) {e.printStackTrace();}}}
}

线程不调用 start() 方法线程不会启动

调用start() 方法会从系统中创建一个线程,新的线程会执行 run 方法,run 方法式线程的入口方法,类型于主线程的 main() 方法。

启动线程之后,线程就会进入就绪状态,随时准备被系统调度,CPU 执行。

两个线程中分别设置了死循环,打印线程执行,可以出看出控制台两个线程都可以打印数据,也就是说两个线程之间宏观上是并发执行的,线程执行的顺序是无序的。

MyThread 线程类的 run() 方法相当于 主线程中的 main() 方法,都是描述线程的入口。

疑问点:为什么调用 start() 方法会自动执行 run() 方法?

因为类Thread中的start方法中,调用了Thread中的run方法。
MyThread继承了Tread类,在MyThread 中重写run方法,就会覆盖掉Thread中的run方法,子类重写父类方法,优先调用子类重写后的方法,如果子类没有重写父类方法,默认执行的是父类的 run 方法,所以子类调用start方法后,实现的是自己的run方法体里面的代码。

3.2 实现 Runnable 接口

  1. 自定义一个类使其实现 Runnable 接口

class MyThread2 implements Runnable { //实现 Runnable 接口@Overridepublic void run() { //重写接口里面的 run 方法//线程运行的代码while (true) {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("线程t执行");}}
}
  1. 创建 Thread 类实例, 调用 Thread 的构造方法时将 Runnable 对象作为 target 参数.

public class Demo2 {public static void main(String[] args) {//创建 Thread 类实例, 调用 Thread 的构造方法时将 Runnable 对象作为 target 参数.Thread t = new Thread(new MyThread2());t.start();// 启动线程while (true) {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("主线程 main 执行");}}
}

这是 Thread 线程类提供的有参构造方法,可以看出里面是 Runnable 接口的引用来接收,我们自定义的线程类由于实现了 Runnable 接口,此时发生向上转型,父接口引用接收子类对象,由于子类重写了 Runnable 接口的 run 方法,所以接口引用可以直接调用子类重写后的 run 方法,如果在 父类想调用子类其他独有的成员变量或者是方法,就需要 向下转型(强制类型转换)。

然后线程对象 t 调用 start() 方法启动线程然后调用 run() 方法。

采用实现接口方式创建一个线程 与 继承 Threard 类 创建一个线程 最终的结果是没什么区别的。


3.3 lambda 表达式创建线程

Thread t = new Thread(() -> {System.out.println("使用匿名类创建 Thread 子类对象");
});t.start();

我们常常在通过创建 Thread 对象的时候,通过创建匿名内部类重写 run() 方法。

这里创建的匿名内部类

lambda 表达式的本质就匿名函数。

语法形式为 () -> {},其中 () 用来描述参数列表,{} 用来描述方法体,-> 为 lambda运算符 ,读作(goes to)。

有时候我们不是必须要自己重写某个匿名内部类的方法,我们可以利用 lambda表达式的接口快速指向一个已经被实现的方法。

public class Demo3 {public static void main(String[] args) throws InterruptedException {Thread t = new Thread( () -> {while (true) {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("线程 T执行");}});t.start(); //启动while (true) {Thread.sleep(1000);System.out.println("主线程Main执行");}}
}

至此,进程的基本认识博主已经分享完了,希望对大家有所帮助,如有不妥之处欢迎批评指正。

本期收录于博主的专栏——JavaEE,适用于编程初学者,感兴趣的朋友们可以订阅,查看其它“JavaEE基础知识”。

下期预告:Thread 类 以及 常见方法

感谢每一个观看本篇文章的朋友,更多精彩敬请期待:保护小周ღ *★,°*:.☆( ̄▽ ̄)/$:*.°★* ‘

相关文章:

【JavaEE】初识线程

一、简述进程认识线程之前我们应该去学习一下“进程" 的概念,我们可以把一个运行起来的程序称之为进程,进程的调度,进程的管理是由我们的操作系统来管理的,创建一个进程,操作系统会为每一个进程创建一个 PCB&…...

智慧水务监控系统-智慧水务信息化平台建设

平台概述柳林智慧水务监控系统(智慧水务信息化平台)是以物联感知技术、大数据、智能控制、云计算、人工智能、数字孪生、AI算法、虚拟现实技术为核心,以监测仪表、通讯网络、数据库系统、数据中台、模型软件、前台展示、智慧运维等产品体系为…...

【Linux】进程优先级前后台理解

环境:centos7.6,腾讯云服务器Linux文章都放在了专栏:【Linux】欢迎支持订阅🌹相关文章推荐:【Linux】冯.诺依曼体系结构与操作系统【Linux】进程理解与学习(Ⅰ)浅谈Linux下的shell--BASH【Linux…...

时序预测 | MATLAB实现基于EMD-GRU时间序列预测(EMD分解结合GRU门控循环单元)

时序预测 | MATLAB实现基于EMD-GRU时间序列预测(EMD分解结合GRU门控循环单元) 目录 时序预测 | MATLAB实现基于EMD-GRU时间序列预测(EMD分解结合GRU门控循环单元)效果一览基本描述模型描述程序设计参考资料效果一览...

python 模拟鼠标,键盘点击

信息爆炸 消息轰炸模拟鼠标和键盘敲击import time from pynput.keyboard import Controller as key_col from pynput.mouse import Button,Controller def keyboard_input(insertword):keyboardkey_col()keyboard.type(insertword)def mouth():mouseController()mouse.press(…...

【CSS】盒子边框 ③ ( 设置表格细线边框 | 合并相邻边框 border-collapse: collapse; )

文章目录一、设置表格细线边框1、表格示例2、合并相邻边框3、完整代码示例一、设置表格细线边框 1、表格示例 给定一个 HTML 结构中的表格 , 默认样式如下 : <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8" />…...

TensorRT量化工具pytorch_quantization代码解析(一)

量化工具箱pytorch_quantization 通过提供一个方便的 PyTorch 库来补充 TensorRT &#xff0c;该库有助于生成可优化的 QAT 模型。该工具包提供了一个 API 来自动或手动为 QAT 或 PTQ 准备模型。 API 的核心是 TensorQuantizer 模块&#xff0c;它可以量化、伪量化或收集张量的…...

【Kubernetes】第二十七篇 - 布署前端项(下)

一&#xff0c;前言 上一篇&#xff0c;介绍了前端项目的部署&#xff1a;项目的创建和 jenkins 配置&#xff1b; 本篇&#xff0c;创建 Deployment、Service&#xff0c;完成前端项目的部署&#xff1b; 二&#xff0c;创建 Deployment 创建 Deployment 配置文件&#xff…...

【MFC】两个ListBox控件数据交互

一.控件ID名称 界面如图下所示&#xff1a; 候选数据列表的ID为&#xff1a; 已选数据列表的ID为&#xff1a; 二.数据添加 可以使用以下代码往框中添加数据&#xff1a; ((CListBox *)GetDlgItem(IDC_LIST_TO_CHO))->AddString("测试数据"); 显示效果如下&#…...

sklearn库学习--SelectKBest 、f_regression

目录 一、SelectKBest 介绍、代码使用 介绍&#xff1a; 代码使用&#xff1a; 二、评分函数 【1】f_regression&#xff1a; &#xff08;1&#xff09;介绍&#xff1a; &#xff08;2&#xff09;F值和相关系数 【2】除了f_regression函数&#xff0c;还有一些适用于…...

蓝桥杯刷题第十三天

第一题&#xff1a;特殊日期问题描述对于一个日期&#xff0c;我们可以计算出年份的各个数位上的数字之和&#xff0c;也可以分别计算月和日的各位数字之和。请问从 1900 年 11 月 1 日至 9999 年 12 月 31 日&#xff0c;总共有多少天&#xff0c;年份的数位数字之和等于月的数…...

CPU 和带宽之间的时空权衡

在 从一道面试题看 TCP 的吞吐极限 一文的开始&#xff0c;我提到在环形域上两个数字比较大小的前提是在同一个半圆内&#xff0c;进而得到滑动窗口最大值被限定在一个环形域的一半。 现在来看更为基本的问题。如果序列号只有 2bit&#xff0c;甚至仅有 1bit&#xff0c;保序传…...

ES+Redis+MySQL,这个高可用架构设计太顶了!

一、背景 会员系统是一种基础系统&#xff0c;跟公司所有业务线的下单主流程密切相关。如果会员系统出故障&#xff0c;会导致用户无法下单&#xff0c;影响范围是全公司所有业务线。所以&#xff0c;会员系统必须保证高性能、高可用&#xff0c;提供稳定、高效的基础服务。 …...

【Maven】Maven的常用命令

目录 一、Maven的常用命令 1、compile 编译命令 2、test 测试命令 3 、clean 清理命令 4、package 打包命令 5、 install 安装命令 6、Maven 指令的生命周期 二、maven 的概念模型 &#x1f49f; 创作不易&#xff0c;不妨点赞&#x1f49a;评论❤️收藏&#x1f499;一…...

python的循环结构

python中有for循环和while循环两种形式。 1. for 循环 可以用for循环来遍历不同类型的对象&#xff0c;如数组、列表、元组、字典、集合或字符串&#xff0c;并对每个元素执行一段代码。 1.1 数组的for循环 用for循环遍历一个数组&#xff0c;并打印出每个元素&#xff1a;…...

五种Python中字典的高级用法

1. 引言 Python中的字典是一种非常有用的数据结构&#xff0c;它允许大家存储键值对。通常来说&#xff0c;字典灵活、高效且易于使用&#xff0c;是Python中最常用的数据结构之一。字典通常被用于统计频率、映射值等任务&#xff0c;但在Python中使用字典也可以达到许多意想不…...

[蓝桥杯单片机]——八到十一届初赛决赛客观题

第八届初赛 一、填空题 采用外部12MHz晶振&#xff0c;经过系统12分频时定时器获得最大定时长度&#xff0c;此时定时器定时脉冲为1MHz&#xff0c;周期为1s&#xff0c;而定时器计时均为16位加法计数器&#xff0c;即计时长度为。 二、 选择题 ①带阻滤波器是指能通过大多数频…...

多线程(初阶)

文章目录一.初始线程(Thread)1.1.线程的概念1.2.线程的优势1.2.1.线程比进程更轻量1.2.2.并发编程1.3.线程和进程的区别二.Thread类方法2.1. java 中创建线程的方法2.1.1. 继承Thread,重写run2.1.2. 实现Ruuable接口2.1.3. 使用匿名内部类,继承Thread2.1.4.使用匿名内部类,实现…...

【Vue从入门到进阶】Node.js安装与配置

✅作者简介&#xff1a;CSDN一位小博主&#xff0c;正在学习前端&#xff0c;欢迎大家一起来交流学习&#x1f3c6; &#x1f4c3;个人主页&#xff1a;白月光777的CSDN博客 &#x1f525;系列专栏&#xff1a;Vue从入门到进阶 &#x1f4ac;个人格言&#xff1a;但行好事&…...

python 正则使用详解

python 正则使用详解什么是正则在 python 中使用正则一些正则的定义python 正则的方法match 从字符串开头匹配正则返回的结果分析&#xff08;重要&#xff09;fullmatch 严格匹配整个字符串search 任意位置开始匹配sub 替换匹配内容subn 以元组方式返回替换结果split 正则切割…...

手游刚开服就被攻击怎么办?如何防御DDoS?

开服初期是手游最脆弱的阶段&#xff0c;极易成为DDoS攻击的目标。一旦遭遇攻击&#xff0c;可能导致服务器瘫痪、玩家流失&#xff0c;甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案&#xff0c;帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...

C++实现分布式网络通信框架RPC(3)--rpc调用端

目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中&#xff0c;我们已经大致实现了rpc服务端的各项功能代…...

SCAU期末笔记 - 数据分析与数据挖掘题库解析

这门怎么题库答案不全啊日 来简单学一下子来 一、选择题&#xff08;可多选&#xff09; 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘&#xff1a;专注于发现数据中…...

1688商品列表API与其他数据源的对接思路

将1688商品列表API与其他数据源对接时&#xff0c;需结合业务场景设计数据流转链路&#xff0c;重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点&#xff1a; 一、核心对接场景与目标 商品数据同步 场景&#xff1a;将1688商品信息…...

【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力

引言&#xff1a; 在人工智能快速发展的浪潮中&#xff0c;快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型&#xff08;LLM&#xff09;。该模型代表着该领域的重大突破&#xff0c;通过独特方式融合思考与非思考…...

DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI

前一阵子在百度 AI 开发者大会上&#xff0c;看到基于小智 AI DIY 玩具的演示&#xff0c;感觉有点意思&#xff0c;想着自己也来试试。 如果只是想烧录现成的固件&#xff0c;乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外&#xff0c;还提供了基于网页版的 ESP LA…...

HTML前端开发:JavaScript 常用事件详解

作为前端开发的核心&#xff0c;JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例&#xff1a; 1. onclick - 点击事件 当元素被单击时触发&#xff08;左键点击&#xff09; button.onclick function() {alert("按钮被点击了&#xff01;&…...

Redis数据倾斜问题解决

Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中&#xff0c;部分节点存储的数据量或访问量远高于其他节点&#xff0c;导致这些节点负载过高&#xff0c;影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...

如何理解 IP 数据报中的 TTL?

目录 前言理解 前言 面试灵魂一问&#xff1a;说说对 IP 数据报中 TTL 的理解&#xff1f;我们都知道&#xff0c;IP 数据报由首部和数据两部分组成&#xff0c;首部又分为两部分&#xff1a;固定部分和可变部分&#xff0c;共占 20 字节&#xff0c;而即将讨论的 TTL 就位于首…...

Java线上CPU飙高问题排查全指南

一、引言 在Java应用的线上运行环境中&#xff0c;CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时&#xff0c;通常会导致应用响应缓慢&#xff0c;甚至服务不可用&#xff0c;严重影响用户体验和业务运行。因此&#xff0c;掌握一套科学有效的CPU飙高问题排查方法&…...