JavaEE——多线程

接着上篇博客我们已经学习了进程的相关概念,了解到进程里面的相关重要属性,那么这篇博客呢我们要学习一个新的知识点——线程!

一、引入进程的目的

首先引入进程这个概念,是为了解决“并发编程”这样的问题。因为CPU 再往小了做,比较困难了,这是因为 CPU 进入了多核心的时代,要想进一步提高程序的执行速度,就需要充分的利用 CPU 的多核资源。
但是呢,多进程编程,已经可以解决并发编程的问题了已经可以利用起来 cpu 多核资源了。

弊端:

进程太重了!(消耗资源多 & 速度慢)。
1、创建一个进程,开销比较大。
2、销毁一个进程,开销也比较大。

3、调度一个进程,开销也比较大。
说进程重,主要就是重在”资源分配/回收。

线程:

所以我们的线程也就应运而生.线程也叫做“轻量级进程"。
目的就是解决并发编程问题的前提下,让创建,销毁,调度的速度,更快一些!
轻的原因:主要是"把申请资源/释放资源"的操作给省下了。

二、多线程的优点

假设小帅开了一家工厂,他在这个工厂里买了一台机器用来生产空调,小帅发现自己的产品销量不错,于是他想加大生产力度,那可以通过什么方法来提高生产效率呢?

方案一:在这个工厂旁边再开一家工厂购买一台机器用来生产空调(多进程的解决方案)

方案二 :在原本的工厂内再购买一台机器用来生产空调(多线程的解决方案)

那么很显然第二种解决方案更划算,场地和空间都是复用之前的,共用一套资源。

1.线程和进程的关系:进程包含线程!

只有第一个线程启动的时候,开销是比较大的.后续线程就省事了个进程可以包含一个线程,也可以包含多个线程.(不能没有)。你线程1 new 的对象在线程2,3,4 里都可以直接使用。线程1 打开的文在线程2,3,4 里都可以直接使用。
同一个进程里的多个线程之间,共用了进程的同一份资源(主要指的是 内存 和 文件描述符表)。
注:操作系统,实际调度的时候是以线程为单位进行调度的.
如果每个进程有多个线程了,每个线程是独立在 CPU 上调度的。

线程是操作系统调度执行的基本单位,每个线程也都有自己的执行逻辑 (执行流)。

2.面试题:进程和线程之间的区别与联系。

1.进程包含线程! 一个进程里面可以有一个线程,也可以有多个线程。


2.进程线程都能解决并发编程问题场景.但是进程在频繁创建和销毁中,开销更高.线程开销更低,(线程比进程更轻量)。


3.进程是系统分配资源(内存,文件资源....) 的基本单位。线程是系统调度执行的基本单位(CPU)。


4进程之间是相互独立的各自有各自的虚拟地址空间,同一个进程内部的多个线程之间,共用同一个内存空间以及文件资源,一个进程挂了其他进程一般都没事。但是一个线程挂了,很可能把整个进程都带走!

三、第一个多线程程序

那么在Java中进行多线程编程的话如何实现呢?


在 Java 标准库中,就提供了一个 Thread 类,来表示/操作线程。
Thread 类也可以视为是 Java 标准库提供的 API。

即创建好的 Thread 实例,其实和操作系统中的线程是一一对应的关系。
操作系统,提供了一组关于线程的 API(C 语言风),Java 对于这组 API 进一步封装了一下,就成了 Thread 类。

(一)、Thread类的基本用法
写法一:继承自Thread,重写run()

那么通过Thread类创建线程有很多种方法,其中最简单的就是创建子类继承自Thread,重写run()方法。

class MyThread extends Thread{@Overridepublic void run() {System.out.println("hello Thread");}
}

注意,run()方法体中描述了这个线程内部要执行哪些代码。因为每个线程都是并发执行的.(各自执行各自的代码)因此就需要告知这个线程,你执行的代码是什么。
run()方法中的逻辑,是在新创建出来的线程中,被执行的代码,意思就是并不是我一定义这个类,一写 run 方法,线程就创建出来了,相当于领导已经把任务安排好了,我还没开始干呢!

public class demo1 {public static void main(String[] args) {Thread t = new MyThread();t.start();}
}

需要调用这里的start()方法,才是真正在系统中创建了线程,才开始真正执行上面的run操作。

那么我们再写一个程序来仔细观察一下线程的执行情况,我们这里通过一个while循环来打印一个语句,通过sleep方法来控制打印的速度。

class MyThread2 extends Thread{@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) {Thread t = new MyThread2();t.start();while (true){System.out.println("hello main");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}
}

那么我们知道,在一个进程中,至少会有一个线程。
在一个java 进程中,也是至少会有一个调用 main 方法的线程(这个线程不是你手动搞出来的)。
自己创建的 t 线程和 自动创建的 main 线程,就是并发执行的关系(宏观上看起来是同时执行)。
此处的"并发 = 并行+并发"宏观上是区分不了并行和并发的.都取决于系统内部的调度

我们可以发现现在两个线程,都是打印一条,就休眠个1s。
当 1s 时间到了之后,系统先唤醒谁呢?
通过运行结果看起来这个顺序不是完全确定(随机的)
每一轮,1s 时间到了之后,到底是先唤醒 main 还是 thread,这是随机的,对于操作系统来说,内部对于线程之间的调度顺序,在宏观上可以认为是随机的,即所谓的——抢占式执行!
那么对于这个随机性,会给多线程编程带来很多其他的麻烦!!

写法二:

创建一个类,实现Runnable接口,再创建Runnable实例传给Thread实例,通过Runnable来描述任务的内容。

class MyRunnable implements Runnable{@Overridepublic void run() {System.out.println("hello java");}
}
public class demo3 {public static void main(String[] args) {Thread t = new Thread(new MyRunnable());t.start();}
}

写法三:匿名内部类

也就是上面两种写法的翻版,通过一个匿名内部类来实现:

public class demo4 {public static void main(String[] args) {Thread t = new Thread(){@Overridepublic void run() {System.out.println("hello javaEE");}};t.start();}
}

* 通过匿名内部类来实现。
 * 创建一个匿名内部类,继承自Thread类。
 * 同时重写run方法。
 * 同时再new出这个匿名内部类的实例。

写法四:匿名内部类的方法2
* new 的 Runnable,针对这个创建的匿名内部类 同时new出的Runnable实例传给Thread的构造方法。
 * 通常认为这种写法好一点 能够做到让线程和线程执行的任务,更好的进行解耦。写代码追求高内聚,低耦合。
 * Runnable 单纯的只是描述了一个任务 至于这个任务是要通过一个进程来执行,还是线程池来执行 Runnable本身并不关心。
public class demo5 {public static void main(String[] args) {Thread t = new Thread(new Runnable() {@Overridepublic void run() {System.out.println("hello 多线程");}});t.start();}
}
写法五:Lambda(可以代替内部类的方式)

public class demo6 {public static void main(String[] args) {Thread t = new Thread(() -> {System.out.println("hello Thread");});t.start();}
}

创建多线程的方式还有很多种,以上五种必须熟练掌握

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/880075.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C++】——多态详解

不管前方的路有多苦,只要走的方向正确,不管多么崎岖不平,都比站在原地更接近幸福。 —— 宫崎骏 《千与千寻》 目录 1、什么是多态? 2、多态的定义及实现 2.1多态的构成条件 ​2.2多态语法细节处理 2.3协变 2.4析构函数的重…

鸿蒙Harmony应用开发,数据驾驶舱页面的实现

先来看看我们要实现的驾驶舱的页面是什么样的 对于这种 响应式布局的页面构建,我们的脑子里面要有一个概念,就是"分而治之"。我们把这个页面进行分割,分割成不同的块然后再来逐个实现. 不难发现,我们可以将这个看到的效…

96. UE5 GAS RPG 实现闪电链技能(一)

闪电链有一个施法的过程,就是在按键按下的过程,会在按下的过程一直持续造成伤害,一直等到条件不满足(技能键位抬起,蓝量不足,被眩晕)时,将结束技能,并退出技能状态。 所以…

FreeRTOS学习——链表list

FreeRTOS学习——链表(列表)list,仅用于记录自己阅读与学习源码 FreeRTOS Kernel V10.5.1 参考大佬的好文章: freertos内核原理 Day1(链表) FreeRTOS-链表的源码解析 *list_t只能存储指向list_item_t的指针。每个list_item_t都…

VMware vCenter Server 7.0U3s 发布下载,新增功能概览

VMware vCenter Server 7.0U3s 下载 - 集中管理 vSphere 环境 Server Management Software | vCenter | 集中管理 vSphere 环境 请访问原文链接:https://sysin.org/blog/vmware-vcenter-7-u3/,查看最新版。原创作品,转载请保留出处。 作者…

YOLO交通目标识别数据集(红绿灯-汽车-自行车-卡车等)

YOLO交通目标识别 数据集 模型 ui界面 ✓图片数量15000,xml和txt标签都有; ✓class:biker,car,pedestrian,trafficLight,trafficLight-Green,trafficLight-GreenLeft, t…

2024年度国自然基金初审不受理的十大原因

我是娜姐 迪娜学姐 ,一个SCI医学期刊编辑,探索用AI工具提效论文写作和发表。 2024年度基金申请已落下帷幕。近日,《中国科学基金》刊登了国自然基金委工作人员总结的2024年度国自然项目分析。一起来看下,为来年再战做准备。 …

【Docker】安装全流程与配置完整镜像源(可安装 nginx)

目录 一、卸载历史版本(选)二、配置 yum 源三、安装 docker四、配置 docker 镜像源加速(选、强烈建议)4.1 配置阿里镜像加速4.2 配置其他镜像源 五、启动 docker参考文章与视频 本文基于 Linux - CentOS 7 操作系统。 一、卸载历史…

面试真题:谈一谈Mysql的分库分表

分表和分库是什么?有什么区别? 分库是一种水平扩展数据库的技术,将数据根据一定规则划分到多个独立的数据库中。每个数据库只负责存储部分数据,实现了数据的拆分和分布式存储。分库主要是为了解决并发连接过多,单机 my…

【2024】前端学习笔记7-颜色-位置-字体设置

学习笔记 1.定义:css2.颜色:color3.字体相关属性:font3.1.字体大小:font-size3.2.字体风格:font - style3.3.字体粗细:font - weight3.4.字体族:font - family 4.位置:text-align 1.…

uniapp快速入门教程,内容来源于官方文档,仅仅记录快速入门需要了解到的知识点

uniapp快速入门教程,内容来源于官方文档,仅仅记录快速入门需要了解到的知识点 目录 介绍uniapp 介绍uniapp x 介绍功能框架图创建项目&发布组件/标签的变化js的变化css的变化工程结构和页面管理 pages.jsonmanifest.json 应用配置组件easycom组件规…

QT For Android开发-打开PPT文件

一、前言 需求: Qt开发Android程序过程中,点击按钮就打开一个PPT文件。 Qt在Windows上要打开PPT文件或者其他文件很容易。可以使用QDesktopServices打开文件,非常方便。QDesktopServices提供了静态接口调用系统级别的功能。 这里用的QDesk…

Isaac Sim 4.2.0 Windows版本打开报 fbgemm.dll 加载错误

方案一:下载缺少的dll复制到目录里即可 可以看到后台命令窗口出现了错误,发生在import pytorch的时候,根据提示,是因为fbgemm.dll缺少依赖,导致加载异常,一般情况是缺少 libomp140.x86_64.dll 这个文件&am…

【BEV 视图变换】Ray-based(2): 代码复现+画图解释 基于深度估计、bev_pool(代码一键运行)

paper:Lift, Splat, Shoot: Encoding Images from Arbitrary Camera Rigs by Implicitly Unprojecting to 3D code:https://github.com/nv-tlabs/lift-splat-shoot 一、完整复现代码(可一键运行)和效果图 import torch import torch.nn as nn import mat…

数模方法论-整数规划

一、基本概念 非线性规划的应用包括工程设计、资源分配、经济模型等。在求解过程中,由于非线性特性,常用的方法有梯度法、牛顿法、启发式算法等。求解非线性规划问题时,解的存在性和唯一性通常较难保证,且可能存在多个局部最优解…

《飞机大战游戏》实训项目(Java GUI实现)(设计模式)(简易)

目录 一、最终实现后,效果如下。 (1)简单介绍本游戏项目(待完善) (2)运行效果图(具体大家自己可以试) 初始运行情况。 手动更换背景图。 通过子弹攻击敌机,累…

Echats 实现CPK (过程能力)研究报告

背景: 实现: Echarts Option 代码示例 option {title: {text: 折线图示例 - X轴为数值},xAxis: {type: value, // X 轴改为数值型min: 0, // 最小值max: 10, // 最大值},yAxis: {type: value},series: [{type: line,data: [[0, 150], [2, 230], [4, 224], [6…

嵌入式单片机STM32开发板详细制作过程--01

大家好,今天主要给大家分享一下,单片机开发板的制作过程,原理图的制作与PCB设计,以及电子元器件采购与焊接。 第一:单片机开发板成品展示 板子正面都有各个芯片的丝印与标号,方便焊接元器件的时候,可以参考。(焊接完成之后,成品图如下) 第二:开发板原理图制作 在制…

FLStudio21Mac版flstudio v21.2.1.3430简体中文版下载(含Win/Mac)

给大家介绍了许多FL21版本,今天给大家介绍一款FL Studio21Mac版本,如果是Mac电脑的朋友请千万不要错过,当然我也不会忽略掉Win系统的FL,链接我会放在文章,供大家下载与分享,如果有其他问题,欢迎…

Spring后端直接用枚举类接收参数,自定义通用枚举类反序列化器

在使用枚举类做参数时,一般会让前端传数字,后端将数字转为枚举类,当枚举类很多时,很可能不知道这个code该对应哪个枚举类。能不能后端直接使用枚举类接收参数呢,可以,但是受限。 Spring反序列默认使用的是J…