[Java基础揉碎]多线程基础

news2025/1/25 4:26:58

 多线程基础

什么是程序, 进程

什么是线程

什么是单线程,多线程

 并发, 并行的概念

单核cpu来回切换, 造成貌似同时执行多个任务, 就是并发;

在我们的电脑中可能同时存在并发和并行;

怎么查看自己电脑的cpu有几核

1.资源监视器查看

2.此电脑图标右键管理- 设备管理器- 处理器 

3.Java代码

线程的基本使用

创建线程的两种方式

实例 (第一种继承Thread)

当mian启动了一个子线程, 主线程不会阻塞, 可以看到在同时执行(如果是多核cpu可能是并行, 单核则是并发)

 JConsole查看线程

控制台输入jconsole

 打开这么一个界面

连接我们的这个类 

切换到线程可以看到这里有两个线程还在跑(就是说主线程结束了, 就不代表进程结束了, 只要子线程未结束, 就不会造成进程的结束, 只有所有线程结束了才会挂掉)

当主线程结束时, 界面上的一个状态

为什么用start

为什么用start方法而不直接掉run方法呢, 因为run方法就是一个普通方法, 如果直接去掉run的话, 相当于就是主线程去调用, start才会真正的启动线程 

 查看源码

// 进入start

 // 进入这个方法

// 这个方法里面有一个start0 

 // 进入start0 , 这个start0 是个native方法, 是本地方法, 是JVM调用的, 底层是c/c++实现

// 真正实现多线程的是start0这个方法, 可以理解为实在start0里面用的多线程的机制调的这个run方法, 而不是run实现了多线程

// start方法调用start0后, 该线程不会立即执行, 只是将线程变成了可运行的状态, 具体什么时候执行, 取决于cpu, 由cpu统一调度

第二种实现Runnable接口

实例

继承接口没有start(), 需要用到另外一种方式 

通过创建一个Thread对象去start

// 为什么这里通过叫Dog对象放在Thread就可以执行到Dog类的run方法呢, 这里使用了一种设计模式[静态代理模式]

// 代理就好比你想送一个东西给你的朋友, 但是你没有时间, 你叫了一个美团跑腿, 或者你想买一张票, 但是你没有时间, 你叫别人和你买, 这个就是代理

--用代码模拟代理模式的实现机制 

// 假设这个就是Thread代理类, 通过构造器可以接收一个实现了Runnable接口的类, 赋值给target, 通过动态绑定执行构造器传进来的run方法

// 代理就是什么呢, 我自己没有start这个方法, 我让你帮我来做这个事情, 最后实现我的run方法, 就好比是买票我没有时间, 你给我买了票, 最后拿给了我

继承Thread和实现Runnable有什么区别

模拟一个售票系统 , 提出一个互斥同步的问题

第一种方式继承Thread 

 

有一个最大的问题, 三个窗口确实都在卖, 但是票都-1了, 还在卖, 导致超卖了 (互斥同步问题)

因为在都执行到这的时候, 假如是2, 三个线程都通过了, 都到下面去进行减减操作了, 每个线程减一, 就变成了减3, 就会变成-1 

第二种方式实现Runnable

将继承改为实现接口, 其余代码一样

main里面  

也会导致超卖, 原因和上面一样 

怎么解决上面超卖的问题 ☆线程同步机制

使用synchronized解决售票问题

将run方法里面代码提取出来放到一个加了synchronized的同步方法里面, 将这个方法在放到线程run里面

 或者加在

分析同步的原理

假如有三个线程, t1, t2, t3, 它们首先会去争夺这把锁(这个锁是放在对象上的),  在t1拿到这个锁的时候,他就进去了, 它会执行完, 然后在把锁放回去, 放回去之后t2和t3再去抢这把锁, t1有没有可能再去抢这把锁, 也是有可能的, 这把锁就要看它是公平锁还是非公平锁(这里是非公平锁), 这个锁实在对象上, 不是在代码块上, 所以我们把这个锁叫对象锁, 它是用对象的某一个位来表示是否有这个锁或者是否被某个线程拿到了

 这把锁实在对象加的, 也叫互斥锁

加在this对象的例子: 

(也可是其他对象, 但是三个线程必须是同一个对象)

静态上加的使用例子: 

注意事项

线程的死锁(一定要避免)

实例:

这是一个 非常经典的死锁, 有两个线程, 第一个线程的flag为true, 进去后先拿到o1的锁, 此时同时线程二flag为false拿到o2的锁, 这时o1, o2的锁都被拿到了, 而第一个线程还想去拿o2的锁就会被阻塞, 第二个线程还想去拿o1的锁也会被阻塞, 都无法往下继续跑就会造成死锁

释放锁

线程的退出

 线程常用的方法

第一组

 注意事项

 方法实例

 执行interrupt中断线程的休眠, 继续执行

在Java中,线程的interrupt是一种用于中断线程执行的机制。当一个线程被interrupt时,它会收到一个中断信号,可以根据这个信号来决定如何处理。

Java中的线程中断机制通过Thread类的interrupt()方法来实现。调用该方法会设置线程的中断状态为true。如果线程处于阻塞状态(如调用了sleep()、wait()、join()等方法),那么它会立即抛出InterruptedException异常并清除中断状态。如果线程没有处于阻塞状态,那么它的中断状态会被设置为true,可以通过isInterrupted()方法来检查线程的中断状态。

当一个线程被interrupt后,可以根据具体情况来处理中断。常见的处理方式有:

  1. 终止线程:可以在run()方法中使用一个循环来检查中断状态,当中断状态为true时,退出循环,终止线程的执行。
  2. 抛出异常:可以在捕获到InterruptedException异常后,根据具体业务逻辑来决定如何处理异常。
  3. 忽略中断:如果线程的执行逻辑不受中断影响,可以选择忽略中断信号。

需要注意的是,interrupt()方法只是设置了线程的中断状态,并不会真正中断线程的执行。线程是否真正中断还取决于具体的业务逻辑和代码实现。

 第二组

yield:

为什么yield不一定礼让成功? 比如有两条线程t1和t2, t1调用yield的时候, 礼让cpu给t2执行,但是如果cpu在资源充足的情况下, 就是cpu觉得能同时兼顾t1和t2的时候, 就有可能礼让不成功, 只有在资源紧张的情况下才大概率礼让成功 

join:
假如有线程t1和t2, 在t1里面去掉t2.join, 这么操作的意思就是在执行t1的时候, 告诉cpu我主动放弃cpu, 让你把t2执行完毕在回头执行我t1

守护线程

 设置守护线程示例

以下代码现在的执行情况是在主线程执行完循环10次以后, 子线程还在继续执行

我希望在主线程执行完成之后, 子线程就算还没执行完毕也会结束,将子线程设置为守护线程就好了

线程的生命周期

线程的生命周期官方文档是有6个, 为什么有的说有7个呢, 因为在runnable中可以在分为 ready 就绪状态和running真正运行状态

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

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

相关文章

安防监控视频平台智能边缘分析一体机视频存储系统客流统计检测算法

智能边缘分析一体机的客流统计检测算法是一种基于人工智能与边缘计算技术的解决方案,专门设计用来实时、准确地统计通过特定区域的人流量。这项技术广泛应用于零售、交通、场馆管理、智慧城市等领域,以帮助管理者更好地理解顾客行为、优化资源配置、提升…

百度百舸 AIAK-LLM 的大模型训练和推理加速实践

本文整理自 4 月 16 日的 2024 百度 Create 大会的公开课分享《百舸 AIAK-LLM:大模型训练和推理加速实践》。 今天要分享的主题是 AI Infra 相关的内容,主要内容分为四部分。 首先和大家一起讨论大模型给基础设施带来的挑战。第二部分则是向大家介绍一个…

深度优先搜索汇总

常用英文 最近公共祖先(Lowest Common Ancestor,简称LCA) posterity,英语单词,主要用作名词,作名词时译为“子孙,后裔;后代”。 什么是深度优先搜索 深度优先搜索,D…

linux安装python3.8

一、卸载损坏的yum并安装 本来想直接下载安装python3.8,结果过程中损坏了yum,导致yum无法使用。 参考了【故障】6、yum不可用_yum命令无法使用-CSDN博客 1、删除python #删除现有的python rpm -qa|grep python|sudo xargs rpm -ev --allmatches --nodeps #强制删除已安装程…

tomcat--应用部署

tomcat根目录结构 Tomcat中默认网站根目录是/usr/local/apache-tomcat-8.5.100/webapps/在Tomcat的webapps目录中,有个非常特殊的目录ROOT,它就是网站默认根目录。将eshop解压后的文件放到这个/usr/local/apache-tomcat-8.5.100/webapps/ROOT中。bbs解压…

QT在场景中利用freetype实现独立的文字绘制子类QxFreeTypeTextItem

QT在场景中利用freetype实现独立的文字绘制子类QxFreeTypeTextItem,继上一章节讲过qt中如何编译freetype Qt编译和使用freetype矢量字库方法https://blog.csdn.net/wangningyu/article/details/138927379#QT利用freetype提取字库图片_qt freetype-CSDN博客文章浏览…

Vitis HLS 学习笔记--资源绑定-使用URAM(1)

目录 1. 简介 2. 代码分析 2.1 存储器代码 2.2 Implementation报告 2.3 存储器类型指定 2.4 存储器初始化 3. 总结 1. 简介 在博文《Vitis HLS 学习笔记--资源绑定-使用URAM-CSDN博客》中,介绍了如何在Vitis HLS环境下设计一个简易的存储器模型。 通过以下…

Spring Boot | SpringBoot 中 自定义 “用户授权管理“ : 自定义“用户访问控制“、自定义“用户登录控制“

目录: 一、SpringBoot 中 自定义 "用户授权管理" ( 总体内容介绍 ) :二、 自定义 "用户访问控制" ( 通过 "HttpSecurity类" 的 authorizeRequests( )方法来实现 "自定义用户访问控制" ) :1.基础项目文件准备2.实现 "自定义身份认…

初识C语言——第二十一天

猜数字小游戏的实现&#xff1a; 学会了之后可以自己制作彩票抽奖&#xff0c;哈哈&#xff01; 代码实现&#xff1a; #include <stdlib.h> #include <time.h>void menu()//无返回值函数 {printf("**************************\n");printf("****…

企业网站开发技术

随着互联网的快速发展&#xff0c;企业网站成为了企业宣传和推广的重要渠道之一。一个好的企业网站不仅可以提升企业的形象&#xff0c;还可以实现在线销售和客户服务等功能。那么&#xff0c;企业网站的开发技术有哪些呢&#xff1f;本文将从前端开发和后端开发两个方面进行讨…

三.使用HashiCorp Vault工具管理数据库

三.ubuntu安装使用HashiCorp Vault工具管理数据库 HashiCorp Vault 是一个基于身份的秘密和加密管理系统。机密是您想要严格控制访问的任何内容,例如 API 加密密钥、密码和证书。Vault 提供由身份验证和授权方法门控的加密服务。使用 Vault 的 UI、CLI 或 HTTP API,可以安全…

废品回收 小程序+APP功能介绍

基于您提供的废品回收应用的开发需求&#xff0c;以下是基于Uniapp&#xff08;用户端和回收员端&#xff09;、Thinkphp5&#xff08;后台&#xff09;、MySQL&#xff08;数据库&#xff09;的综合解决方案的概述。 一、技术栈选择 前端&#xff1a;Uniapp&#xff08;跨平…

51单片机入门:I2C通讯协议

I2C通讯协议 I2C简介 串口通信只能在两个设备之间进行&#xff0c;如果是三个设备相互通讯&#xff0c;那么每个设备需要两组串口&#xff0c;实际上是3组相互独立的串口通信。如果是4个设备相互通信就更加麻烦了&#xff0c;最突出的问题就是线路连接比较复杂。 为了解决这个…

请问空三前启动引擎,提示这个错误是什么情况?

答&#xff1a;在AppData-Local-GEngine目录下找到G3DEngineConfig.ini&#xff0c;检查ServerCheckCMD后面是否存在路径 &#xff0c;正常是为空&#xff0c;异常是为存在路径&#xff0c;需要清空该路径&#xff0c;然后重新启动引擎即可 重建大师是一款专为超大规模实景三维…

Python 提取PDF表格数据并保存到TXT文本或Excel文件

目录 安装Python库 Python提取PDF表格数据并保存到文本文档 Python提取PDF表格数据并保存到Excel文档 PDF文件常用于存储和共享各种类型的文档&#xff0c;这些文档可能包括大量的数据表格。通过提取这些PDF表格数据&#xff0c;我们可以将其导入到Excel、数据库或统计软件等…

基于openEuler22.03 LTS环境的容器项目实训——分布式微服务项目部署

一、说明 本文配置环境为VMware虚拟机&#xff08;4核CPU&#xff0c;8 GB内存&#xff0c;40GB磁盘&#xff09;&#xff0c;OS为openEuler 22.03 LTS &#xff0c;虚拟机要求能联网。 二、安装docker环境 2.1 安装docker相关软件包 [rootnode01 ~]# dnf -y install docker…

PCIE V3.0物理层协议学习笔记

一、说明 PCI-Express(peripheral component interconnect express)是一种高速串行计算机扩展总线标准&#xff0c;它原来的名称为“3GIO”&#xff0c;是由英特尔在2001年提出的&#xff0c;旨在替代旧的PCI&#xff0c;PCI-X和AGP总线标准。 PCIe属于高速串行点对点双通道高…

Ubuntu 安装 eclipse 的详细过程及工程创建和编译配置

目录 一、安装环境二、下载依赖 java jdk三、下载 eclipse四、安装4.1 java 环境4.2 eclipse 安装4.3 打开 eclipse 五、配置 eclipse5.1 新建 C 工程5.2 工具链 配置5.3 头文件路径5.4 链接库5.5 编译 一、安装环境 Ubuntu 版本&#xff1a;22.04.3 位数&#xff1a;64-bit 二…

其实解决问题的方法很简单

大家好&#xff01;我是编码小哥&#xff0c;欢迎关注&#xff0c;持续分享更多实用的编程经验和开发技巧&#xff0c;共同进步&#xff01; 本例是一个动态数组的例子&#xff0c;实现数据的增加、删除、根据索引修改数值、获取数值。 dynamic_array.c #include "dy…

redis-stack部署概要

第一步&#xff0c;下载redis-stack 下载链接&#xff1a;Downloads - Redis 第二步&#xff0c;redis安装包解压缩 gzip -d redis-stack-server-7.2.0-v10.rhel8.x86_64.tar.gz tar -xvf redis-stack-server-7.2.0-v10.rhel8.x86_64.tar 第三步&#xff0c;编辑etc下的redis…