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

 多线程基础

什么是程序, 进程

什么是线程

什么是单线程,多线程

 并发, 并行的概念

单核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.mzph.cn/web/13154.shtml

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

相关文章

k8s 二进制安装 详细安装步骤

目录 一 实验环境 二 操作系统初始化配置(所有机器) 1,关闭防火墙 2,关闭selinux 3,关闭swap 4, 根据规划设置主机名 5, 做域名映射 6,调整内核参数 7, 时间同步 三 部署 dock…

uniapp vu3 scroll-view 滚动到指定位置

设置 scroll-view <scroll-view :scroll-y"true" :scroll-with-animation"true" :scroll-top"scrollTop" :style"height:${height}px"><view v-for"item in 10" :id"box${item}">box {{item}}</v…

原生IP介绍

原生IP&#xff0c;顾名思义&#xff0c;即初始真实IP地址&#xff0c;是指从互联网服务提供商获得的IP地址&#xff0c;IP地址在互联网与用户之间直接建立联系&#xff0c;不需要经过代理服务器代理转发。 原生IP具备以下特点。 1.直接性 原生IP可以直接连接互联网&#xff…

337_C++_内存对齐操作,内存分配、或其他需要数据对齐的场合中是很常见的操作

size_t ImagesCache::_alignSize(size_t srcSz, size_t alnSz) {if (0 == alnSz) {printf("[ImagesCache] Incorrect input parameters\n");return srcSz;

代码随想录算法训练营第五十四天

第二题我看了很久还是没太明白&#xff0c;我发现理解动规有一点点吃力了啊&#xff0c;努努力。 392.判断子序列 总感觉在不等于的时候&#xff0c;应该是dp[i][j] dp[i-1][j-2]; 这里其实按他那个图会更好理解一点。 class Solution { public:bool isSubsequence(string s, …

Gone框架介绍19 -如何进行单元测试?

gone是可以高效开发Web服务的Golang依赖注入框架 github地址&#xff1a;https://github.com/gone-io/gone 文档地址&#xff1a;https://goner.fun/zh/ 请帮忙在github上点个 ⭐️吧&#xff0c;这对我很重要 &#xff1b;万分感谢&#xff01;&#xff01; 文章目录 单元测试…

CentOs安装

安装 开发工具 &#xff1a;GCC、 JDK、mysql 如果出现蓝屏&#xff0c;要在BIOS开启虚拟化支持&#xff0c;或者移除打印机。

Google:站长移除无效网址

当您的网址不需要呈现在Google站长中时&#xff0c;您可以在站长工具中移除网址 操作步骤&#xff1a;登录Google站长&#xff0c;绑定网站完成后&#xff0c;点击左侧删除 >> 输入网址 如果遇到一些网址&#xff0c;可以找寻网址间的规律&#xff0c;比如说&#xff0…

2024生日快乐祝福HTML源码

源码介绍 2024生日快乐祝福HTML源码&#xff0c;源码由HTMLCSSJS组成&#xff0c;记事本打开源码文件可以进行内容文字之类的修改&#xff0c;双击html文件可以本地运行效果&#xff0c;也可以上传到服务器里面&#xff0c; 源码截图 源码下载 2024生日快乐祝福HTML源码

Shell脚本 <<EOF ... EOF语法(Here Document)(特殊的输入重定向方式)(定界符)

文章目录 Here Document语法Here Document 的基本语法使用场景 关于定界符定界符不是变量定界符在 Here Document 中只是一个字符串&#xff0c;主要功能是标记输入文本的开始和结束&#xff0c;使用时应遵循最佳实践格式要求例子和说明如何使用定界符定界符可重复使用&#xf…

Spring数据访问全攻略:从JdbcTemplate到声明式事务

上文讲到 —— 航向数据之海&#xff1a;Spring的JPA与Hibernate秘籍 本文目录 四. JdbcTemplate的使用定义JdbcTemplate及其在Spring中的作用展示如何使用JdbcTemplate简化数据库操作1. 配置JdbcTemplate2. 使用JdbcTemplate查询数据3. 打印查询结果 五. Spring的事务管理介绍…

桥接模式

桥接模式&#xff1a;在这种模式下&#xff0c;虚拟机就像是局域网中一台独立的主机&#xff0c;能够访问网内任何一台机器。在桥接模式下&#xff0c;必须为虚拟系统手动配置IP地址、子网掩码&#xff0c;并且这些配置需要与宿主机器处于同一网段&#xff0c;以便虚拟系统和宿…

leetcode-42. 接雨水(双指针,前缀)

42. 接雨水 /*** param {number[]} height* return {number}*/ var trap function (height) {let len height.length;let pre_max new Array(len).fill(0);let suf_max new Array(len).fill(0);pre_max[0] height[0];suf_max[len - 1] height[len - 1];for (let i 1; i…

queue使用

C的queue是一种先进先出&#xff08;FIFO&#xff09;的数据结构&#xff0c;可以用来存储一系列元素。它属于STL&#xff08;Standard Template Library&#xff09;的一部分&#xff0c;以queue模板类的形式提供。 要使用queue&#xff0c;需要包含头文件&#xff0c;并使用…

Linux shell编程学习笔记49:strings命令

0 前言 在使用Linux的过程中&#xff0c;有时我们需要在obj文件或二进制文件中查找可打印的字符串&#xff0c;那么可以strings命令。 1. strings命令 的功能、格式和选项说明 我们可以使用命令 strings --help 来查看strings命令的帮助信息。 pupleEndurer bash ~ $ strin…

在k8s中搭建elasticsearch高可用集群,并对数据进行持久化存储

&#x1f407;明明跟你说过&#xff1a;个人主页 &#x1f3c5;个人专栏&#xff1a;《洞察之眼&#xff1a;ELK监控与可视化》&#x1f3c5; &#x1f516;行路有良友&#xff0c;便是天堂&#x1f516; 目录 一、引言 1、Elasticsearch简介 2、k8s简介 二、环境准备 …

Git项目管理——提交项目和版本回退(二)

个人名片&#xff1a; &#x1f393;作者简介&#xff1a;嵌入式领域优质创作者&#x1f310;个人主页&#xff1a;妄北y &#x1f4de;个人QQ&#xff1a;2061314755 &#x1f48c;个人邮箱&#xff1a;[mailto:2061314755qq.com] &#x1f4f1;个人微信&#xff1a;Vir2025WB…

android绘制多个黑竖线条

本文实例为大家分享了android绘制多个黑竖线条展示的具体代码&#xff0c;供大家参考&#xff0c;具体内容如下 1.写一个LinearLayout的布局&#xff0c;将宽度写成5dp将高度写成match_parent. 2.在写一个类继承LinearLayout&#xff0c;用LayoutInflater实现子布局的在这个L…

train_gpt2_fp32.cu - main

llm.c/test_gpt2_fp32.cu at master karpathy/llm.c (github.com) 源码 // ---------------------------------------------------------------------------- // main training loop int main(int argc, char *argv[]) {// read in the (optional) command line argumentsco…

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

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