JavaEE初阶---多线程编程(一.线程与进程)
目录
🤣一.线程与进程的概念与联系:
进程的基本概念:
线程的基本概念:
进程和线程的区别与联系:
🙃代码执行实列:
1.通过继承Thread父类来实现多线程
2.通过实现Runnable接口来实现多线程:
3.通过Lambda表达式来实现多线程:
😇Thread类的常见属性和构造方法:
🤣一.线程与进程的概念与联系:
一张漫画,生动阐明进程进程与线程的关系:
进程的基本概念:
- 什么是进程?→
🧐🧐定义:进程是一个具有一定独立功能的程序在一个数据集合上依次动态执行的过程。进程是一个正在执行的程序的实例,包括程序计数器,寄存器和程序变量的当前值。
- 进程有哪些特征?→
1.进程依赖于程序的运行而存在,进程是动态的,程序是静态的
2.进程是操作系统进行资源分配和调度的一个独立单位(CPU除外,线程是处理器任务调度和执行的基本单位);
3.每个进程拥有独立的地址空间,地址空间包括代码区,数据区和堆栈区,进程之间的地址空间是间隔的,互不影响
线程的基本概念:
- 什么是线程?
🦉🦉定义:一个线程就是一个“执行流”,每个线程之间都可以按照顺序执行自己的代码,多个线程之间“同时”执行着多份代码
- 为什么要用到线程?
⾸先, "并发编程" 成为 "刚需":
为了充分利用CPU的资源,避免出现“一核工作,多核围观”的情况,我们可以通过编写特殊的代码,把多个CPU核心,充分利用起来,这样的代码就称为“并发编程”,多进程的编程,就是一种典型的并发编程。虽然多进程能够解决问题,但是随着对于效率的要求越来越高,就希望有更好的方法来实现并发编程。而多进程的编程,最大的问题,就是进程太“重”,创建进程/销毁进程的开销比较大(时间,空间),一旦场景需要频繁的创建和销毁进程,开销就非常明显了→最典型的是服务器开发,针对每一个发出请求的客户端,都创建一个单独的进程,由这个进程负责给客户端提供服务。为了解决进程开销比较大的问题,就发明了线程(Thread),线程可以理解为更加轻量级的进程,也能解决开发并发程序的问题,但是创建/销毁的开销,要比进程更低。
进程和线程的区别与联系:
- 1.进程包含线程:
一个进程里至少包含一个线程(主线程),也可以包含多个线程。不能没有线程
2.进程是系统分配资源的基本单位
3.线程是系统调度执行的基本单位
- 4.同一个进程里的线程之间,共用一份系统资源(内存,硬盘,网络宽带等),尤其是内存资源,就是代码中定义的变量/对象等信息,编程中,多个线程,是可以共用同一份变量的~
- 5.多线程是当下实现并发编程的主流方式,通过多线程,就可以充分利用好多核CPU。但是,也不是线程数目越多,就越好,线程数目达到一定程度,把多个核心都利用充分之后,此时继续增加线程,无法再提高效率,甚至可能会影响效率(线程的调度,也是有开销的)
- 6.多个线程之间,可能会互相影响,线程安全问题。一个线程抛出异常,也可能会把其他线程一起带走
- 7.多个进程之间,一般不会互相影响,一个进程奔溃了,不会影响到其他进程(进程的隔离性)
🙃代码执行实列:
1.通过继承Thread父类来实现多线程
//1.通过继承Thread父类来实现进程
class MyThread extends Thread{@Overridepublic void run(){//这里写的代码,就是即将创建的线程,要执行的逻辑while(true){System.out.println("hello thread");try {Thread.sleep(1000);} catch (InterruptedException e) {//throw new RuntimeException(e);e.printStackTrace();}}}
}
public class Demo1 {public static void main(String[] args) throws InterruptedException {MyThread t = new MyThread();//创建线程->运行hello main 和 hello thread 并发执行,同时打印t.start();//run 不会创建线程,也是再主线程中执行逻辑//t.run();只循环打印hello threadwhile(true){System.out.println("hello main");Thread.sleep(1000);}}
}
也可以通过匿名内部类来实现:
//通过匿名内部类来创建多线程
public class Demo3 {public static void main(String[] args) throws InterruptedException {Thread t = new Thread(){@Overridepublic void run(){while(true){System.out.println("hello thread");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}};t.start();while(true){System.out.println("hello main");Thread.sleep(1000);}}
}
运行结果:
2.通过实现Runnable接口来实现多线程:
//2.通过实现Runnable接口来实现多线程
class MyRunnable implements Runnable{//描述线程里要完成的逻辑是啥@Overridepublic void run() {while(true){System.out.println("hello thread");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}
}
public class Demo2 {public static void main(String[] args) throws InterruptedException {MyRunnable runnable = new MyRunnable();Thread t = new Thread(runnable);t.start();while(true){System.out.println("hello main");Thread.sleep(1000);}}
}
也可以通过匿名内部类来实现:
public class Demo4 {public static void main(String[] args) throws InterruptedException {//通过匿名内部类来编写Thread t = new Thread(new Runnable() {@Overridepublic void run() {while(true){System.out.println("hello thread");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}});t.start();while(true){System.out.println("hello main");Thread.sleep(1000);}}
}
3.通过Lambda表达式来实现多线程:
//通过lambda表达式来进行编写
public class Demo5 {public static void main(String[] args) throws InterruptedException {Thread t = new Thread(()->{while(true){System.out.println("hello thread");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}});t.start();while(true){System.out.println("hello main");Thread.sleep(1000);}}
}
😇Thread类的常见属性和构造方法:
- Thread类常见的构造方法:
- Thread类常见的属性:
public class Demo6 {public static void main(String[] args) {Thread t = new Thread(()->{while(true){System.out.println("hello thread");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}},"自定义线程");//->线程名字为自定义线程t.start();System.out.println("线程ID : " + t.getId());System.out.println("线程名字: " + t.getName());System.out.println("线程状态: " + t.getState());System.out.println("线程执行顺序:" + t.getPriority());}
}
运行结果:
Runnable正在运行,实际上Java没有Running这个线程状态,把正在CPU上运行,和随时可以调度到CPU上运行的,都统称为Runnable
- 前台线程&后台线程
后台线程:如果这个线程执行过程中,不能阻止进程结束(虽然线程执行着,但是进程就要结束了,此时这个线程也会随之被带走)这样的线程就称为“后台线程”
前台线程:如果某个线程执行过程中,能阻止进程的结束,此时这个线程就是“前台线程”
前台线程和后台线程,主要是影响程序的退出
public class Demo7 {//设置前public static void main1(String[] args) {Thread t1 = new Thread(()->{while(true){System.out.println("hello thread");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}});t1.start();}//设置后public static void main(String[] args) {Thread t2 = new Thread(()->{while(true){System.out.println("hello thread");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}});//把 t 设置线程为后台线程(守护线程),不能在阻止程序结束了t2.setDaemon(true);t2.start();}
}
结语: 写博客不仅仅是为了分享学习经历,同时这也有利于我巩固知识点,总结该知识点,由于作者水平有限,对文章有任何问题的还请指出,接受大家的批评,让我改进。同时也希望读者们不吝啬你们的点赞+收藏+关注,你们的鼓励是我创作的最大动力!
相关文章:

JavaEE初阶---多线程编程(一.线程与进程)
目录 🤣一.线程与进程的概念与联系: 进程的基本概念: 线程的基本概念: 进程和线程的区别与联系: 🙃代码执行实列: 1.通过继承Thread父类来实现多线程 2.通过实现Runnable接口来实现多线程…...
react+vite创建
要在本地初始化一个结合了React和Vite的项目,你可以遵循以下步骤: 1、安装Node.js: 确保你的机器上已安装了Node.js。如果未安装,请前往Node.js官网下载并安装。 2、使用终端或命令提示符: 打开你的终端(…...
软考 系统架构设计师系列知识点之杂项集萃(29)
接前一篇文章:软考 系统架构设计师系列知识点之杂项集萃(28) 第46题 以下描述中,( )不是嵌入式操作系统的特点。 A. 面向应用,可以进行裁剪和移植 B. 用于特定领域,不需要支持多任…...

[Qt开发]当我们在开发兼容高分辨率和高缩放比、高DPI屏幕的软件时,我们在谈论什么。
前言 最近在开发有关高分辨率屏幕的软件,还是做了不少尝试的,当然我们也去网上查了不少资料,但是网上的资料也很零碎,说不明白,这样的话我就做个简单的总结,希望看到这的你可以一次解决你有关不同分辨率下…...

uniapp视频组件层级太高,解决方法使用subNvue原生子体窗口
目录 前言 先看一下uniapp官网的原话: subNvue的一些参数介绍 subNvues使用方法: 绑定id 显示 subNvue 弹出层 subNvue.show() 参数信息 subNvue.hide() 参数信息 在使用subNvue 原生子体窗口 遇到的一些问题 前言 nvue 兼容性 以及使用方式 控…...
java项目使用jsch下载ftp文件
pom <dependency><groupId>com.jcraft</groupId><artifactId>jsch</artifactId><version>0.1.55</version> </dependency>demo1:main方法直接下载 package com.example.controller;import com.jcraft.jsch.*; im…...

指针(初阶1)
一.指针是什么 通俗的讲,指针就是地址,其存在的意义就像宾馆房间的序号一样是为了更好的管理空间。 如下图: 如上图所示,指针就是指向内存中的一块空间,也就相当于地址 二.一个指针的大小是多少 之前我们学习过&#x…...
MySQL实体类框架
实现mysql数据库的增删改查功能 import com.mchange.v2.collection.MapEntry; import lombok.Data; import org.junit.jupiter.api.Test;import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.lang.reflect.*; import java.sql.*; …...

数据结构之初始泛型
找往期文章包括但不限于本期文章中不懂的知识点: 个人主页:我要学编程(ಥ_ಥ)-CSDN博客 所属专栏:数据结构(Java版) 目录 深入了解包装类 包装类的由来 装箱与拆箱 面试题 泛型 泛型的语法与使用…...

【网络编程开发】7.TCP可靠传输的原理
7.TCP可靠传输的原理 TCP实现可靠传输的原理主要基于序列号和确认应答、超时重传、滑动窗口、连接管理机制以及拥塞控制等多重机制。 TCP(Transmission Control Protocol),即传输控制协议,是网络通信中的一种重要协议࿰…...

视觉SLAM十四讲:从理论到实践(Chapter8:视觉里程计2)
前言 学习笔记,仅供学习,不做商用,如有侵权,联系我删除即可 一、目标 1.理解光流法跟踪特征点的原理。 2.理解直接法是如何估计相机位姿的。 3.实现多层直接法的计算。 特征点法存在缺陷: 二、光流(Optical Flow) …...

C语言过度C++语法补充(面向对象之前语法)
目录 1. C相较于C语言新增的语法 0. C 中的输入输出 1. 命名空间 1. 我们如何定义一个命名空间? 2. 如何使用一个命名空间 3. 命名空间中可以定义什么? 4. 在 相同或者不同 的文件中如果出现 同名的命名空间 会如何? 5. 总结~~撒花~~…...

类和对象(二)(C++)
初始化列表 class Date{public:Date(int year, int month, int day){_year year;_month month;_day day;}private:int _year;int _month;int _day;}; 虽然上述构造函数调用之后,对象中已经有了一个初始值,但是不能将其称为对对象中成员变量的初始化…...

Chrome DevTools解密:成为前端调试大师的终极攻略
Chrome DevTools是一套内置于Google Chrome浏览器中的开发者工具,它允许开发者对网页进行调试、分析和优化。本文将全面介绍DevTools的功能、使用方法以及注意事项,帮助开发者更好地利用这些工具来提升开发效率和网页性能。 一、简介 1. DevTools是什么…...

【python】OpenCV—Cartoonify and Portray
参考来自 使用PythonOpenCV将照片变成卡通照片 文章目录 1 卡通化codecv2.medianBlurcv2.adaptiveThresholdcv2.kmeanscv2.bilateralFilter 2 肖像画cv2.divide 1 卡通化 code import cv2 import numpy as npdef edge_mask(img, line_size, blur_value):gray cv2.cvtColor(…...

制作AI问答机器人:从0到1的完整指南
在数字化转型的浪潮中,企业正追求更高效、智能的客户服务解决方案。AI问答机器人以其快速响应、全天候服务和持续学习的能力,成为了提升客户满意度和加速业务发展的关键工具。本文将深入探讨如何制作一个企业级的AI问答机器人,并强调其功能体…...

mysql 数据库datetime 类型,转换为DO里面的long类型后,只剩下年了,没有了月和日
解决方法也简单: 自定义个一个 Date2LongTypeHandler <resultMap id"BeanResult" type"XXXX.XXXXDO"><result column"gmt_create" property"gmtCreate" jdbcType"DATE" javaType"java.lang.Long&…...

信息系统项目管理师0148:输出(9项目范围管理—9.3规划范围管理—9.3.3输出)
点击查看专栏目录 文章目录 9.3.3 输出 9.3.3 输出 范围管理计划 范围管理计划是项目管理计划的组成部分,描述将如何定义、制定、监督、控制和确认项 目范围。范围管理计划用于指导如下过程和相关工作: ①制定项目范围说明书;②根据详细项目范…...
解决 SQLyog 连接 MySQL 8 连不上和 SQLyog Trial 试用到期的问题
今天发现 SQLyog 突然连不上 MySQL 了,跟之前不一样的地方就是我升级了 MySQL,升级到了 MySQL 8。 原来是因为 MySQL 8 引入了新的密码验证机制。在 MySQL 8 中默认的密码验证插件从 mysql_native_password 更换为 caching_sha2_password。我的 SQLYog …...

go语言内置预编译 //go:embed xxx 使用详解
在go语言里面,我们可以使用一个“类注释”的语法来来让编译器帮助我们在编译的时候将一些文件或者目录读取到指定的变量中来供我们使用。 go:embed语法: //go:embed 文件或者目录路径 var 变量名 变量类型 说明: 文件或者目录路径 可以…...

docker详细操作--未完待续
docker介绍 docker官网: Docker:加速容器应用程序开发 harbor官网:Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台,用于将应用程序及其依赖项(如库、运行时环…...
在rocky linux 9.5上在线安装 docker
前面是指南,后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...

关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案
问题描述:iview使用table 中type: "index",分页之后 ,索引还是从1开始,试过绑定后台返回数据的id, 这种方法可行,就是后台返回数据的每个页面id都不完全是按照从1开始的升序,因此百度了下,找到了…...

HTML 列表、表格、表单
1 列表标签 作用:布局内容排列整齐的区域 列表分类:无序列表、有序列表、定义列表。 例如: 1.1 无序列表 标签:ul 嵌套 li,ul是无序列表,li是列表条目。 注意事项: ul 标签里面只能包裹 li…...
在四层代理中还原真实客户端ngx_stream_realip_module
一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡(如 HAProxy、AWS NLB、阿里 SLB)发起上游连接时,将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后,ngx_stream_realip_module 从中提取原始信息…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放
简介 前面两期文章我们介绍了I2S的读取和写入,一个是通过INMP441麦克风模块采集音频,一个是通过PCM5102A模块播放音频,那如果我们将两者结合起来,将麦克风采集到的音频通过PCM5102A播放,是不是就可以做一个扩音器了呢…...

SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现
摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序,以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务,提供稳定高效的数据处理与业务逻辑支持;利用 uniapp 实现跨平台前…...

【论文阅读28】-CNN-BiLSTM-Attention-(2024)
本文把滑坡位移序列拆开、筛优质因子,再用 CNN-BiLSTM-Attention 来动态预测每个子序列,最后重构出总位移,预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵(S…...

vue3+vite项目中使用.env文件环境变量方法
vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量,这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...
大学生职业发展与就业创业指导教学评价
这里是引用 作为软工2203/2204班的学生,我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要,而您认真负责的教学态度,让课程的每一部分都充满了实用价值。 尤其让我…...