JavaSE学习笔记总结day19
今日内容
二、线程安全的集合
三、死锁
四、线程通信
五、生产者消费者
六、线程池
零、 复习昨日
创建线程的几种方式 1) 继承 2) 实现Runnable 3) callable接口 Future接口 4) 线程池
启动线程的方法 start()
线程的几种状态
什么是线程不安全
setName getName
Thread.currentThread()
join
sleep
synchronized
一、作业
售卖后车票
package com.qf.homework;public class Window implements Runnable {// 票(加static,被该类所有对象共享)private static int ticket = 100;// 售票任务@Overridepublic void run() {while (true) {synchronized (Window.class) {if (ticket > 0) {try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace( );}System.out.println(Thread.currentThread( ).getName( ) + "有余票,正在售出" + ticket);ticket--;} else {System.out.println("票已售完");return;}}}}
}
public static void main(String[] args) {new Thread( new Window() ,"窗口1").start();new Thread( new Window() ,"窗口2").start();new Thread( new Window() ,"窗口3").start();}
二、线程安全的集合
StringBuffer是线程安全的,是因为每个方法都加上synchronized,即都是同步方法
StringBuilder没有加
ArrayList是线程不安全
Vector 是线程安全
HashMap 是线程不安全
Hashtable 是线程安全
比HashMap安全,比Hashtable快,即安全又快的集合ConcurrentHashMap[很重要]
三、死锁
死锁: 互相持有对方的锁还不释放
public class MyLock {static Object zuo = new Object();static Object you = new Object();
}
public class Boy extends Thread{@Overridepublic void run() {synchronized (MyLock.zuo){System.out.println("男朋友-拿到左筷子" );synchronized (MyLock.you) {System.out.println("男朋友-拿到右筷子,开吃" );}}}
}
public class Girl extends Thread{@Overridepublic void run() {synchronized (MyLock.you){System.out.println("女朋友-拿到右筷子" );synchronized (MyLock.zuo) {System.out.println("女朋友-拿到左筷子,开吃" );}}}
}
public class TestDeadLock {public static void main(String[] args) {new Boy().start();new Girl().start();}
}
男生先拿到zuo锁,再去获得you锁即可吃饭
但是you锁在女生那里,女生需要获得zuo锁才能吃饭
即 男生需要的you锁被女生拿着,女生需要的zuo锁被男生拿着
互相持有对方的锁,还不释放,就会出现"死锁" 程序卡死,不往下执行,持续阻塞
四、线程通信
线程通信,就是线程之间产生联系.
即通知,例如线程A执行到一定时候会
停下
,同时通知另外的线程B执行,
线程B执行到一定时候,也停下,通知线程A执行
以上操作需要Object类的方法
- wait() 让当前线程等待
- notify() 唤醒一个处于等待状态的线程
特殊的:
- wait和notify方法需要在同步方法或者同步代码块内执行
- wait会让当前线程进入等待状态,让出资源,其他线程可以执行
问 wait和sleep有什么区别?
答:
wait是Object类的方法,sleep是Thread类方法
wait和sleep都可以让当前线程进入阻塞状态
但是wait阻塞当前线程,会让出系统资源,其他线程可执行;但是sleep阻塞当前线程,会持有锁不释放,其他线程无法执行
wait需要在同步方法或同步代码快中使用,但是sleep可以在同步或非同步都可以使用
ps: 搞个表格
wait sleep 不同点 属于Object类中的方法,需要再同步代码块或同步方法中。 属于Thread方法,可以同步或不同步的执行。 相同 让线程阻塞,会让出系统资源 让线程阻塞,持有锁不释放资源
问 为什么wait和notify方法要设计在Object类中?
答: 因为锁可以是任意对象,有因为wait和notify需要被 锁对象调用,所以锁对象任意,wait和notify方法也能被任意对象调用,所以就设计在Object类中,因为Object类是所有类的父类
需求: 昨天打印机方法,让print1()和print2()方法交替执行
package com.qf.notify;public class Printer {// 具体哪台打印机执行的标志private int flag = 1;// 现在使用同步方法,print1和print2方法由同一个对象打印机对象调用// print1方法和print2方法锁是同一个,是this,即打印机对象public synchronized void print1() {if (flag != 1) {try {// 锁是谁,就用谁调用wait// 当前线程就陷入等待,会让出资源释放锁this.wait();} catch (InterruptedException e) {e.printStackTrace( );}}System.out.print("1 ");System.out.print("2 ");System.out.print("3 ");System.out.print("4 ");System.out.print("\r\n");// 干完活,修改标志flag = 2;// 通知另外一个处于等待状态的线程// 锁是谁,用谁调用方法this.notify();}public synchronized void print2() {if (flag != 2) {try {this.wait();} catch (InterruptedException e) {e.printStackTrace( );}}System.out.print("A ");System.out.print("B ");System.out.print("C ");System.out.print("D ");System.out.print("\r\n");flag = 1;this.notify();}
}
// 测试
public class TestNotify {public static void main(String[] args) {Printer printer = new Printer( );new Thread(){@Overridepublic void run() {while (true){printer.print1();}}}.start();new Thread(){@Overridepublic void run() {while (true){printer.print2();}}}.start();}
}
换用同步代码块实现
package com.qf.notify;public class Printer {// 锁对象private Object obj = new Object();// 具体哪台打印机执行的标志private int flag = 1;// 现在使用同步方法,print1和print2方法由同一个对象打印机对象调用// print1方法和print2方法锁是同一个,是this,即打印机对象public void print1() {// 同步代码块,现在锁是字节码文件synchronized(Printer.class) {if (flag != 1) {try {// 锁是谁,就用谁调用wait// 当前线程就陷入等待,会让出资源释放锁// 用字节码锁来调用wait方法Printer.class.wait( );} catch (InterruptedException e) {e.printStackTrace( );}}System.out.print("1 ");System.out.print("2 ");System.out.print("3 ");System.out.print("4 ");System.out.print("\r\n");// 干完活,修改标志flag = 2;// 通知另外一个处于等待状态的线程// 只能唤醒在此对象监视器(加过锁的)上等待的单个线程.// 如果没有加锁,直接调用该方法唤醒线程,会报错IllegalMonitorStateException// 锁是谁,用谁调用方法Printer.class.notify( );}}public void print2() {synchronized( Printer.class) {if (flag != 2) {try {Printer.class.wait( );} catch (InterruptedException e) {e.printStackTrace( );}}System.out.print("A ");System.out.print("B ");System.out.print("C ");System.out.print("D ");System.out.print("\r\n");flag = 1;Printer.class.notify( );}}
}
- void start() 开启线程
- void run() 执行线程的方法- run() 方法是start开启线程后,JVM自动调用
- void setName(String name) 给线程设置名字
- String getName() 获得线程的名字
- static Thread currentThread() 返回当前正在执行的线程对象
- setPriority(int priority) 设置优先级- 级别是1-10 ,默认是5
- getPriority() 获得优先级
- join() 加入线程,等待该线程终止
- join(int milles) 加入线程,最大等待直到毫秒数
- void setDaemon(boolean on) 设置守护线程
- static void yield() 礼让线程,暂停当前线程,让其他线程执行
- static void sleep(long milles) 线程休眠
- void stop() 结束当前线程,线程死亡
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NV4f7qWm-1678065007263)(D:\前锋学习笔记\笔记\image-20230306090803972.png)]
相关文章:

JavaSE学习笔记总结day19
今日内容 二、线程安全的集合 三、死锁 四、线程通信 五、生产者消费者 六、线程池 零、 复习昨日 创建线程的几种方式 1) 继承 2) 实现Runnable 3) callable接口 Future接口 4) 线程池 启动线程的方法 start() 线程的几种状态 什么是线程不安全 setName getName Thread.curr…...

FreeSql使用
目的: 1.方库分表 2.主从分离 3.分布式事务 过程: 官网:指南 | FreeSql 官方文档 1.Startup.cs 添加配置(本地数据库MySql) ConfigureServices: Func<IServiceProvider, IFreeSql> fsql r >{IFreeSql …...

Hadoop集群搭建,基于3.3.4hadoop和centos8【图文教程-从零开始搭建Hadoop集群】,常见问题解决
Hadoop集群搭建,基于3.3.4hadoop和centos8【小白图文教程-从零开始搭建Hadoop集群】,常见问题解决Hadoop集群搭建,基于3.3.4hadoop1.虚拟机的创建1.1 第一台虚拟机的创建1.2 第一台虚拟机的安装1.3 第一台虚拟机的网络配置1.3.1 主机名和IP映…...

UE4 材质学习 (焚烧材质)
效果步骤随便从网上下载一张图片(地址:链接/链接),导入UE中新建一个材质函数这里命名为“E_Function”双击打开该材质函数,由于需要输出变发光和变透明两种效果,因此这里需要两个输出节点:分别命…...
【c++】STL常用算法2—常用查找算法
文章目录常用查找算法findfind_ifadjacent_findbinary_searchcountcount_if常用查找算法 算法简介: find//查找元素 find_if//按条件查找元素 adjacent_find//查找相邻重复元素 binary_search//二分查找法 count//统计元素个数 count_if//按条件统计元素个数find …...

史上最全最详细的Java架构师成长路径图,程序员必备
从新手码农到高级架构师,要经过几步?要多努力,才能成为为人倚重的技术专家?本文将为你带来一张程序员发展路径图,但你需要知道的是,天下没有普适的道理,具体问题还需具体分析,实践才…...

第五章 事务管理
1.事务概念 *什么是事务:事务是数据库操作最基本单元,逻辑上是一组操作,要么都成功,要么都失败 *事务的特性(ACID):原子性、隔离性、一致性、持久性 2.搭建事务操作环境 *模拟场景ÿ…...

Redis:主从同步
Redis:主从同步一. 概述二. 原理(1) 全量同步(2) 增量同步(3) 优化Redis主从集群三. 总结一. 概述 引入: Redis主从集群采用一个Master负责写,多个Slave负责读的方式(读多写少),那么如何让读取数据时多个从…...

Unity Animator.Play(stateName, layer, normalizedTime) 播放动画函数用法
原理 接口: public void Play(string stateName, int layer -1, float normalizedTime float.NegativeInfinity);参数含义stateName动画状态机的某个状态名字layer第几层的动画状态机,-1 表示播放第一个状态或者第一个哈希到的状态normalizedTime从s…...

python学习——【第三弹】
前言 上一篇文章 python学习——【第二弹】中学习了python中的运算符内容,这篇文章接着学习python中的流程控制语句。 流程控制指的是代码运行逻辑、分支走向、循环控制,是真正体现我们程序执行顺序的操作。流程控制一般分为顺序执行、条件判断和循环控…...
科技云报道:AI大模型背后,竟是惊人的碳排放
科技云报道原创。 自从ChatGPT这样的大型语言模型在全球引起轰动以来,很少有人注意到,训练和运行大型语言模型正在产生惊人的碳排放量。 虽然OpenAI和谷歌都没有说过他们各自产品的计算成本是多少,但据第三方研究人员分析,ChatG…...

如何根据实际需求选择合适的三维实景建模方式?
随着实景三维中国建设的推进,对三维实景建模的数字化需求大幅增加。由于三维实景建模具有采集速度快、计算精度高等建模优势,引起了各个行业的高度关注。三维实景建模是一种应用数码相机或者激光扫描仪对现有场景进行多角度环视拍摄,然后利用…...

CENTO OS上的网络安全工具(十八)ClickHouse及编程环境部署
这篇其实去年就写好了,孰知就在12月31日那一天打进决赛圈,一躺,二过年,三休假,四加班,居然到了三个月以后,才有机会将它发出来…… 一年也就四个季度不是,实在是光阴荏苒,…...

Java中class文件的格式
常见的class文件格式如下图所示,下面我将对一下格式一一作出解释。 一、magic 该部分主要是对语言类型的规范,只有magic这个部分是CAFEBABE时才能被检测为Java语言,否则则不是。 二、minor version和major version minor version主要表示了…...
C++排序算法
排序算法复习 冒泡排序 链接:https://www.runoob.com/w3cnote/bubble-sort.html 每次循环对比【相邻】两个元素,将最大的元素放到数组最后 void bubbleSort(int* arr, int n){//每次确认一个元素的最终位置,循环n-1次即可确认全部元素的最…...

JAVA后端部署项目三步走
1. JAVA部署项目三步走 1.1 查看 运行的端口 lsof -i:8804 (8804 为端口) 发现端口25111被监听 1.2 杀死进程,终止程序 pid 为进程号 kill -9 pid 1.3 后台运行jar包 nohup java -jar -Xms128M -Xmx256M -XX:MetaspaceSize128M -XX:MaxM…...
php使用zookeeper实现分布式锁
介绍 一、zookeeper和redis实现分布式锁的对比 1、redis 分布式场景应用比较广泛,redis分布式锁,其实需要自己不断去尝试获取锁,比较消耗性能;zk分布式锁,获取不到锁,注册个监听器即可,不需要不…...

力扣-可回收且低脂的产品
大家好,我是空空star,本篇带大家了解一道超级超级超级简单的力扣sql练习题。 文章目录前言一、题目:1757. 可回收且低脂的产品二、解题1.正确示范①提交SQL运行结果2.正确示范②提交SQL运行结果3.正确示范③提交SQL运行结果4.正确示范④提交S…...

代码随想录刷题-数组-二分查找
文章目录写在前面原理习题题目1思路和代码题目-2写在前面 这个专栏是记录我刷代码随想录过程中的随想和总结。每一小节都是根据自己的理解撰写的,文章比较短,主要是为了记录和督促自己。刷完一章后,我会再单独整理一篇文章来总结和分享。 本…...

HCIA复习1
HCIA复习 抽象语言---->编码 编码---->二进制 二进制--->电信号 处理电信号 OSI参考模型----OSI/RM 应用层 表示层 会话层 传输层 端口号:0-65535;1-1023是注明端口 网络层 IP地址 数据链路层 物理层 ARP协议 正向ARP---通过IP地址获取目的MAC地…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地
借阿里云中企出海大会的东风,以**「云启出海,智联未来|打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办,现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...
【Java学习笔记】Arrays类
Arrays 类 1. 导入包:import java.util.Arrays 2. 常用方法一览表 方法描述Arrays.toString()返回数组的字符串形式Arrays.sort()排序(自然排序和定制排序)Arrays.binarySearch()通过二分搜索法进行查找(前提:数组是…...

Docker 运行 Kafka 带 SASL 认证教程
Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明:server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...

高频面试之3Zookeeper
高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个?3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制(过半机制࿰…...
Golang dig框架与GraphQL的完美结合
将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用,可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器,能够帮助开发者更好地管理复杂的依赖关系,而 GraphQL 则是一种用于 API 的查询语言,能够提…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)
UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中,UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化…...

如何在最短时间内提升打ctf(web)的水平?
刚刚刷完2遍 bugku 的 web 题,前来答题。 每个人对刷题理解是不同,有的人是看了writeup就等于刷了,有的人是收藏了writeup就等于刷了,有的人是跟着writeup做了一遍就等于刷了,还有的人是独立思考做了一遍就等于刷了。…...
Java线上CPU飙高问题排查全指南
一、引言 在Java应用的线上运行环境中,CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时,通常会导致应用响应缓慢,甚至服务不可用,严重影响用户体验和业务运行。因此,掌握一套科学有效的CPU飙高问题排查方法&…...

SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)
上一章用到了V2 的概念,其实 Fiori当中还有 V4,咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务),代理中间件(ui5-middleware-simpleproxy)-CSDN博客…...
Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?
在大数据处理领域,Hive 作为 Hadoop 生态中重要的数据仓库工具,其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式,很多开发者常常陷入选择困境。本文将从底…...