Java学习--多线程2
2.线程同步
2.1卖票【应用】
-
案例需求
某电影院目前正在上映国产大片,共有100张票,而它有3个窗口卖票,请设计一个程序模拟该电影院卖票
-
实现步骤
-
定义一个类SellTicket实现Runnable接口,里面定义一个成员变量:private int tickets = 100;
-
在SellTicket类中重写run()方法实现卖票,代码步骤如下
-
判断票数大于0,就卖票,并告知是哪个窗口卖的
-
卖了票之后,总票数要减1
-
票卖没了,线程停止
-
定义一个测试类SellTicketDemo,里面有main方法,代码步骤如下
-
创建SellTicket类的对象
-
创建三个Thread类的对象,把SellTicket对象作为构造方法的参数,并给出对应的窗口名称
-
启动线程
-
-
代码实现
public class SellTicket implements Runnable {private int tickets = 100;//在SellTicket类中重写run()方法实现卖票,代码步骤如下@Overridepublic void run() {while (true) {if(ticket <= 0){//卖完了break;}else{try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}ticket--;System.out.println(Thread.currentThread().getName() + "在卖票,还剩下" + ticket + "张票");}}} } public class SellTicketDemo {public static void main(String[] args) {//创建SellTicket类的对象SellTicket st = new SellTicket();//创建三个Thread类的对象,把SellTicket对象作为构造方法的参数,并给出对应的窗口名称Thread t1 = new Thread(st,"窗口1");Thread t2 = new Thread(st,"窗口2");Thread t3 = new Thread(st,"窗口3");//启动线程t1.start();t2.start();t3.start();} }
2.2卖票案例的问题【理解】
-
卖票出现了问题
-
相同的票出现了多次
-
出现了负数的票
-
-
问题产生原因
线程执行的随机性导致的,可能在卖票过程中丢失cpu的执行权,导致出现问题
2.3同步代码块解决数据安全问题【应用】
-
安全问题出现的条件
-
是多线程环境
-
有共享数据
-
有多条语句操作共享数据
-
-
如何解决多线程安全问题呢?
- 基本思想:让程序没有安全问题的环境
-
怎么实现呢?
-
把多条语句操作共享数据的代码给锁起来,让任意时刻只能有一个线程执行即可
-
Java提供了同步代码块的方式来解决
-
-
同步代码块格式:
synchronized(任意对象) { 多条语句操作共享数据的代码 }synchronized(任意对象):就相当于给代码加锁了,任意对象就可以看成是一把锁
-
同步的好处和弊端
-
好处:解决了多线程的数据安全问题
-
弊端:当线程很多时,因为每个线程都会去判断同步上的锁,这是很耗费资源的,无形中会降低程序的运行效率
-
-
代码演示
public class SellTicket implements Runnable {private int tickets = 100;private Object obj = new Object();@Overridepublic void run() {while (true) {synchronized (obj) { // 对可能有安全问题的代码加锁,多个线程必须使用同一把锁//t1进来后,就会把这段代码给锁起来if (tickets > 0) {try {Thread.sleep(100);//t1休息100毫秒} catch (InterruptedException e) {e.printStackTrace();}//窗口1正在出售第100张票System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets + "张票");tickets--; //tickets = 99;}}//t1出来了,这段代码的锁就被释放了}} }public class SellTicketDemo {public static void main(String[] args) {SellTicket st = new SellTicket();Thread t1 = new Thread(st, "窗口1");Thread t2 = new Thread(st, "窗口2");Thread t3 = new Thread(st, "窗口3");t1.start();t2.start();t3.start();} }
2.4同步方法解决数据安全问题【应用】
-
同步方法的格式
同步方法:就是把synchronized关键字加到方法上
修饰符 synchronized 返回值类型 方法名(方法参数) { 方法体; }同步方法的锁对象是什么呢?
this
-
静态同步方法
同步静态方法:就是把synchronized关键字加到静态方法上
修饰符 static synchronized 返回值类型 方法名(方法参数) { 方法体; }同步静态方法的锁对象是什么呢?
类名.class
-
代码演示
public class MyRunnable implements Runnable {private static int ticketCount = 100;@Overridepublic void run() {while(true){if("窗口一".equals(Thread.currentThread().getName())){//同步方法boolean result = synchronizedMthod();if(result){break;}}if("窗口二".equals(Thread.currentThread().getName())){//同步代码块synchronized (MyRunnable.class){if(ticketCount == 0){break;}else{try {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}ticketCount--;System.out.println(Thread.currentThread().getName() + "在卖票,还剩下" + ticketCount + "张票");}}}}}private static synchronized boolean synchronizedMthod() {if(ticketCount == 0){return true;}else{try {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}ticketCount--;System.out.println(Thread.currentThread().getName() + "在卖票,还剩下" + ticketCount + "张票");return false;}} }public class Demo {public static void main(String[] args) {MyRunnable mr = new MyRunnable();Thread t1 = new Thread(mr);Thread t2 = new Thread(mr);t1.setName("窗口一");t2.setName("窗口二");t1.start();t2.start();}}
2.5Lock锁【应用】
虽然我们可以理解同步代码块和同步方法的锁对象问题,但是我们并没有直接看到在哪里加上了锁,在哪里释放了锁,为了更清晰的表达如何加锁和释放锁,JDK5以后提供了一个新的锁对象Lock
Lock是接口不能直接实例化,这里采用它的实现类ReentrantLock来实例化
-
ReentrantLock构造方法
方法名 说明 ReentrantLock() 创建一个ReentrantLock的实例 -
加锁解锁方法
方法名 说明 void lock() 获得锁 void unlock() 释放锁 -
代码演示
public class Ticket implements Runnable {//票的数量private int ticket = 100;private Object obj = new Object();private ReentrantLock lock = new ReentrantLock();@Overridepublic void run() {while (true) {//synchronized (obj){//多个线程必须使用同一把锁.try {lock.lock();if (ticket <= 0) {//卖完了break;} else {Thread.sleep(100);ticket--;System.out.println(Thread.currentThread().getName() + "在卖票,还剩下" + ticket + "张票");}} catch (InterruptedException e) {e.printStackTrace();} finally {lock.unlock();}// }}} }public class Demo {public static void main(String[] args) {Ticket ticket = new Ticket();Thread t1 = new Thread(ticket);Thread t2 = new Thread(ticket);Thread t3 = new Thread(ticket);t1.setName("窗口一");t2.setName("窗口二");t3.setName("窗口三");t1.start();t2.start();t3.start();} }
2.6死锁【理解】
-
概述
线程死锁是指由于两个或者多个线程互相持有对方所需要的资源,导致这些线程处于等待状态,无法前往执行
-
什么情况下会产生死锁
- 资源有限
- 同步嵌套
-
代码演示
public class Demo {public static void main(String[] args) {Object objA = new Object();Object objB = new Object();new Thread(()->{while(true){synchronized (objA){//线程一synchronized (objB){System.out.println("小康同学正在走路");}}}}).start();new Thread(()->{while(true){synchronized (objB){//线程二synchronized (objA){System.out.println("小薇同学正在走路");}}}}).start();} }
相关文章:
Java学习--多线程2
2.线程同步 2.1卖票【应用】 案例需求 某电影院目前正在上映国产大片,共有100张票,而它有3个窗口卖票,请设计一个程序模拟该电影院卖票 实现步骤 定义一个类SellTicket实现Runnable接口,里面定义一个成员变量:privat…...
【Virtualization】Windows11安装VMware Workstation后异常处置
安装环境 Windows 11 专业版 22H2 build 22621.1265 VMware Workstation 17 Pro 17.0.0 build-20800274 存在问题 原因分析 1、BIOS未开启虚拟化。 2、操作系统启用的虚拟化与Workstation冲突。 3、操作系统启用内核隔离-内存完整性保护。 处置思路 1、打开“资源管理器”…...
第四章.神经网络—BP神经网络
第四章.神经网络 4.3 BP神经网络 BP神经网络(误差反向传播算法)是整个人工神经网络体系中的精华,广泛应用于分类识别,逼近,回归,压缩等领域,在实际应用中,大约80%的神经网络模型都采用BP网络或BP网络的变化…...
如何压缩RAR格式文件?
RAR是我们日常生活工作中经常用到的压缩文件格式之一,那么RAR文件如何压缩呢? 不管压缩哪种格式的压缩文件,我们都需要用到压缩软件。针对RAR格式,我们可以选择最常见的WinRAR,当然如果有同样适用于RAR格式的压缩软件…...
JS 执行机制 详解(附图)
一、JS是单线程JS语言的一大特点就是单线程,也就是说,同一个时间只能做一件事。这是JS这门脚本语言诞生的使命所致——用来处理页面中用户的交互,以及操作DOM而诞生的。单线程就意味着,所有任务需要排队,前一个任务结束…...
华为OD机试真题Java实现【 计算面积】真题+解题思路+代码(20222023)
计算面积 绘图机器的绘图笔初始位i在原点(0.0)。 机器启动后其绘图笔按下面规则绘制直线: 1 )尝试沿着横向坐标轴正向绘制直线,直到给定的终点值E, 2 )期间可通过指令在纵坐标轴方向进行偏移。井同时绘制直线,偏移后按规则1绘制直线;指令的格式为X offsetY。表示在横坐标X…...
【JVM】运行时数据区与对象的创建流程
4、运行时数据区 4.1、运行时数据区介绍 运行时数据区也就是JVM在运⾏时产生的数据存放的区域,这块区域就是JVM的内存区域,也称为JVM的内存模型——JMM 堆空间(线程共享):存放new出来的对象 元空间(线程共…...
flutter- JSON解析框架使用方法json_serializable
对于目前来说,大部分的API网络请求的通讯内容数据格式都是JSON。JSON返回的都是字符串,假如要取到data里面的id,去直接字符串截取肯定是不行的,要通过一定的方式把它解析成Map或者解析成对象,再去处理它。像一些简单的…...
第十三届蓝桥杯国赛 C++ B 组 J 题——搬砖(AC)
目录1.搬砖1.题目描述2.输入格式3.输出格式4.样例输入5.样例输出6.数据范围7.原题链接2.解题思路3.Ac_code1.搬砖 1.题目描述 这天,小明在搬砖。 他一共有 nnn 块砖, 他发现第 iii 砖的重量为 wiw_{i}wi, 价值为 viv_{i}vi 。他突然想从这些 砖中选一些出来从…...
Spring Cloud Nacos源码讲解(十)- Nacos服务端服务发现处理
Nacos集群数据同步 当我们有服务进行注册以后,会写入注册信息同时会触发ClientChangedEvent事件,通过这个事件,就会开始进行Nacos的集群数据同步,当然这其中只有有一个Nacos节点来处理对应的客户端请求,其实这其中…...
C++ 修改程序进程的优先级(Linux,Windows)
文章目录1、Linux1.1 常用命令1.1.1 不占用终端运行和后台运行方式1.1.2 查询进程1.1.3 结束进程1.1.4 优先级命令1.2 C 代码示例1.2.1 代码一1.2.2 代码二2、Windows2.1 简介2.2 函数声明2.3 C 代码示例2.3.1 代码一2.3.2 代码二结语1、Linux 1.1 常用命令 1.1.1 不占用终端…...
同步和异步promise
进程和线程进程(厂房):程序的运行环境线程(工人):进行运算的东西同步和异步同步:一件事干完才去干下一件事,前面的代码不执行,后面的代码也不执行。同步的代码可能会出现…...
CHATGPT是新的“搜索引擎终结者”吗?百度是否慌了
ChatGPT 以其非凡的自然语言处理 (NLP) 能力和清晰的响应风靡全球,有望带来一场重大的技术革命。在不知不觉中,叙事转向了ChatGPT与百度的对决,因为来自OpenAI的智能和健谈的聊天机器人已经慢慢获得了“潜在的百度终结…...
力扣-订单最多的客户
大家好,我是空空star,本篇带大家了解一道简单的力扣sql练习题。 文章目录前言一、题目:586. 订单最多的客户二、解题1.正确示范①提交SQL运行结果2.正确示范②提交SQL运行结果3.正确示范③提交SQL运行结果4.正确示范④提交SQL运行结果5.其他总…...
MyBatis学习笔记(六) —— MyBatis的各种查询功能
6、MyBatis的各种查询功能 6.1、查询一个实体类对象 SelectMapper.java接口 /*** 根据用户id查询用户信息* param id* return*/ User getUserById(Param("id") int id);SelectMapper.xml <!--User getUserById(Param("id") int id)--> <selec…...
2023年最新详细教程!手把手教你搭建Hexo + GitLab个人博客
文章目录前言一、安装和配置环境1.安装 Git2.安装 Node.js二、新建博客项目1.GitLab配置CI/CD自动化部署1.1 GitLab新建项目1.2 GitLab自建Runners1.2.1 下载gitlab-runner1.2.2 注册Runners1.2.3 安装Runners并启动1.3 添加.gitlab-ci.yml文件2.拉取和推送hexo blog2.1 拉取he…...
centos7安装
centos7安装制作U盘启动盘下载镜像下载 UltralISO制作启动盘使用U盘安装系统修改模式为 UEFI调整BOOT option保存重启进入安装界面安装图形界面安装搜狗输入法制作U盘启动盘 下载镜像 去官网下载镜像,找到 mirrors链接(速度快) 选择一个中…...
java String类(超详细,含常用方法、面试题,内存图,案例)
String类一、String类的特点二、String 类的常见构造方法三、String常见的面试题1.字符串常量池2.String s "abc"与String s new String("abc")区别3.字符拼接4.常量优化机制四、String常用方法1. 比较字符串内容2. 遍历字符串3.截取字符串4.替换字符串5…...
哈希表以及哈希冲突
目录 哈希表 哈希冲突 1. 冲突发生 2. 比较常见的哈希函数 3. 负载因子调节(重点) 散列表的载荷因子概念 负载因子和冲突率的关系 冲突-解决-闭散列 线性探测 二次探测 冲突-解决-开散列 结尾 我们在前面讲解了TerrMap(Set)的底层是一个搜索…...
测试——基本概念
概念 测试和调试有以下几点区别: 测试是测试人员进行的工作,调试是开发人员调试是发现并解决问题,测试只是发现问题测试贯穿于整个项目的生命周期,而调试主要在编码阶段 测试人员一般有如下的工作: 需求分析&#x…...
HTML 列表、表格、表单
1 列表标签 作用:布局内容排列整齐的区域 列表分类:无序列表、有序列表、定义列表。 例如: 1.1 无序列表 标签:ul 嵌套 li,ul是无序列表,li是列表条目。 注意事项: ul 标签里面只能包裹 li…...
django filter 统计数量 按属性去重
在Django中,如果你想要根据某个属性对查询集进行去重并统计数量,你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求: 方法1:使用annotate()和Count 假设你有一个模型Item,并且你想…...
相机从app启动流程
一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...
Spring Boot面试题精选汇总
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...
BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...
【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)
升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点,但无自动故障转移能力,Master宕机后需人工切换,期间消息可能无法读取。Slave仅存储数据,无法主动升级为Master响应请求ÿ…...
go 里面的指针
指针 在 Go 中,指针(pointer)是一个变量的内存地址,就像 C 语言那样: a : 10 p : &a // p 是一个指向 a 的指针 fmt.Println(*p) // 输出 10,通过指针解引用• &a 表示获取变量 a 的地址 p 表示…...
【HarmonyOS 5】鸿蒙中Stage模型与FA模型详解
一、前言 在HarmonyOS 5的应用开发模型中,featureAbility是旧版FA模型(Feature Ability)的用法,Stage模型已采用全新的应用架构,推荐使用组件化的上下文获取方式,而非依赖featureAbility。 FA大概是API7之…...
写一个shell脚本,把局域网内,把能ping通的IP和不能ping通的IP分类,并保存到两个文本文件里
写一个shell脚本,把局域网内,把能ping通的IP和不能ping通的IP分类,并保存到两个文本文件里 脚本1 #!/bin/bash #定义变量 ip10.1.1 #循环去ping主机的IP for ((i1;i<10;i)) doping -c1 $ip.$i &>/dev/null[ $? -eq 0 ] &&am…...
起重机起升机构的安全装置有哪些?
起重机起升机构的安全装置是保障吊装作业安全的关键部件,主要用于防止超载、失控、断绳等危险情况。以下是常见的安全装置及其功能和原理: 一、超载保护装置(核心安全装置) 1. 起重量限制器 功能:实时监测起升载荷&a…...
