当前位置: 首页 > news >正文

线程——线程同步

案例:卖票

需求:某电影院目前正在上映国产大片,共有100张票,而它有三个窗口卖票,请设计一个程序模拟该电影院卖票

思路:

        定义一个类SellTicket实现Runnable接口,里面定义一个成员变量:private in tickets = 100;

        在SellTicket类中重写run()方法实现卖票,代码步骤如下

                判断票数大于0,就卖票,并告知是那个窗口卖的

                卖了票之后,总票数减1

                票没了,也可能有人来问,所以这里用死循环让卖票的动作一直执行

定义一个测试类SellTicketDemo,里面有main()方法,代码步骤如下

                创建SellTicket类对象

                创建三个Thread类的对象,把SellTicket对象作为构造方法的参数,并给出对应的窗口名称

                启动线程

package com.aynu14;//定义一个类SellTicket实现Runnable接口,里面定义一个成员变量:private in tickets = 100;
public class SellTicket implements Runnable{private int tickets=100;//在SellTicket类中重写run()方法实现卖票,代码步骤如下@Overridepublic void run() {
//            判断票数大于0,就卖票,并告知是那个窗口卖的
//            卖了票之后,总票数减1
//            票没了,也可能有人来问,所以这里用死循环让卖票的动作一直执行while (true){if (tickets>0) {System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets + "张票");tickets--;}}}
}
package com.aynu14;//    需求:某电影院目前正在上映国产大片,共有100张票,而它有三个窗口卖票,请设计一个程序模拟该电影院卖票
//
//        思路:
//        定义一个类SellTicket实现Runnable接口,里面定义一个成员变量:private in tickets = 100;
//        在SellTicket类中重写run()方法实现卖票,代码步骤如下
//            判断票数大于0,就卖票,并告知是那个窗口卖的
//            卖了票之后,总票数减1
//            票没了,也可能有人来问,所以这里用死循环让卖票的动作一直执行
//
//        定义一个测试类SellTicketDemo,里面有main()方法,代码步骤如下
//            创建SellTicket类对象
//            创建三个Thread类的对象,把SellTicket对象作为构造方法的参数,并给出对应的窗口名称
//            启动线程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();}
}

 卖票出现了问题

        相同的票出现多次

        出现了负数的票

问题原因

        线程执行的随机性导致的

卖票案例数据安全问题的解决

        为什么出现问题?(这也是我们判断多线程程序是否会有数据安全问题的标准)

                是否具有多线程环境

                是否有共享数据

                是否有多条语句操作共享数据

如何解决多线程安全问题

        基本思想:让程序没有安全问题的环境

怎么实现呢?

        把多条语句操作共享数据的代码锁起来,让任意时刻只能有一个线程执行即可

        java提供了同步代码块的方式来解决

锁多条语句操作共享数据,可以使用同步代码块实现

格式:

        synchronized(任意对象){

                多条语句操作共享数据的代码

}

synchronized(任意对象):就相当于给代码加锁了,任意对象就可以看成是一把锁

同步的好处和弊端

        好处:解决了多线程的数据安全问题

        弊端:当线程很多时,因为每个线程都会去判断同步上的锁,这里很耗费资源的,无形中会降低程序的运行效率

package com.aynu14;//定义一个类SellTicket实现Runnable接口,里面定义一个成员变量:private in tickets = 100;
public class SellTicket implements Runnable{private int tickets=100;private Object obj=new Object();//在SellTicket类中重写run()方法实现卖票,代码步骤如下@Overridepublic void run() {
//            判断票数大于0,就卖票,并告知是那个窗口卖的
//            卖了票之后,总票数减1
//            票没了,也可能有人来问,所以这里用死循环让卖票的动作一直执行//相同票出现了多次
//        while (true){
//            //tickest=100;
//            //t1,t2,t3
//            //假设t1线程抢到CPU执行权
//        if (tickets>0) {
//            //通过Sellp()方法来模拟出票时间
//            try {
//                Thread.sleep(100);
//                //t1线程休息100毫秒
//                //t2线程抢到CPU的执行权,t2线程就开始执行,执行到这里的时候,t2线程休息100毫秒
//                //t3线程抢到CPU的执行权,t3线程就开始执行,执行到这里的时候,t3线程休息100毫秒
//            } catch (InterruptedException e) {
//                throw new RuntimeException(e);
//            }
//            //假设线程按照顺序醒过来
//            //t1抢到CPU的执行权,在控制台输出,窗口1正在出售第100张票
//            System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets + "张票");
//            //t2抢到CPU的执行权,在控制台输出,窗口2正在出售第100张票
//            //t3抢到CPU的执行权,在控制台输出,窗口3正在出售第100张票
//            tickets--;
//
//            //如果这三个线程还是按照顺序来,这里就执行了3次--操作,最终票就变成了97
//            }
//        }//出现了负数的票while (true){synchronized (obj) {//tickest=1;//t1,t2,t3//假设t1线程抢到CPU执行权if (tickets > 0) {//通过Sellp()方法来模拟出票时间try {Thread.sleep(100);//t1线程休息100毫秒//t2线程抢到CPU的执行权,t2线程就开始执行,执行到这里的时候,t2线程休息100毫秒//t3线程抢到CPU的执行权,t3线程就开始执行,执行到这里的时候,t3线程休息100毫秒} catch (InterruptedException e) {throw new RuntimeException(e);}//假设线程按照顺序醒过来//t1抢到CPU执行权,在控制台输出,窗口1正在出售第1张票//假设t1继续拥有CPU的执行权,就会执行tickets--操作,ticket=0;//t2抢到CPU执行权,在控制台输出,窗口2正在出售第0张票//假设t2继续拥有CPU的执行权,就会执行tickets--操作,ticket=-1;//t3抢到CPU执行权,在控制台输出,窗口2正在出售第-1张票//假设t3继续拥有CPU的执行权,就会执行tickets--操作,ticket=-2;System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets + "张票");tickets--;}}}}
}
package com.aynu14;//    需求:某电影院目前正在上映国产大片,共有100张票,而它有三个窗口卖票,请设计一个程序模拟该电影院卖票
//
//        思路:
//        定义一个类SellTicket实现Runnable接口,里面定义一个成员变量:private in tickets = 100;
//        在SellTicket类中重写run()方法实现卖票,代码步骤如下
//            判断票数大于0,就卖票,并告知是那个窗口卖的
//            卖了票之后,总票数减1
//            票没了,也可能有人来问,所以这里用死循环让卖票的动作一直执行
//
//        定义一个测试类SellTicketDemo,里面有main()方法,代码步骤如下
//            创建SellTicket类对象
//            创建三个Thread类的对象,把SellTicket对象作为构造方法的参数,并给出对应的窗口名称
//            启动线程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();}
}

同步方法:就是把synchronized关键字加到方法上

        格式:

        修饰符synchronized返回值类型 方法名(方法参数){ }

同步方法的锁对象是什么呢

        this

同步静态方法,就是把synchornized关键字加到静态方法上

        格式

        修饰符static synchronized返回值类型 方法名(方法参数)

同步静态方法的锁对象是什么呢

        类名.class

相关文章:

线程——线程同步

案例:卖票 需求:某电影院目前正在上映国产大片,共有100张票,而它有三个窗口卖票,请设计一个程序模拟该电影院卖票 思路: 定义一个类SellTicket实现Runnable接口,里面定义一个成员变量&#xff…...

安卓录屏使用VirtualDisplay虚拟屏幕;MediaRecorder,媒体录影机;

1.跟截屏一样,判断权限,然后在onActivityResult里面给mediaProjection赋能; 2.初始化录像机: //初始化Recorder录像机 fun initRecorderStart() { //新建Recorder val displayMetrics DisplayMetrics() val width displayMetri…...

Java FileChannel文件的读写实例

一、概述: 文件通道FileChannel是用于读取,写入,文件的通道。FileChannel只能被InputStream、OutputStream、RandomAccessFile创建。使用fileChannel.transferTo()可以极大的提高文件的复制效率,他们读和写直接建立了通道&#x…...

2023 年男生还推荐报计算机专业吗?

计算机专业确实是一个非常热门的专业,就业前景也很广阔。 但是,近些年随着各个大学对计算机专业及其相关专业疯狂扩招,而且每年的毕业人口都在增多,行业是根本容纳不下的,就业竞争力度也急剧上升。因此,选…...

【华为OD机试真题】积木最远距离(相同数字的积木游戏1)(javapython)

相同数字的积木游戏1 知识点数组循环map 时间限制:1s 空间限制:256MB 限制语言:不限 题目描述: 小华和小薇一起通过玩积木游戏学习数学。 他们有很多积木,每个积木块上都有一个数字,积木块上的数字可能相同。 小华随机拿一些积木挨着排成一排,请小薇找到这排积木中数…...

STM32F103RCT6驱动SG90舵机-完成正反转角度控制

一、SG90舵机介绍 SG90是一种微型舵机,也被称为伺服电机。它是一种小型、低成本的直流电机,通常用于模型和机器人控制等应用中。SG90舵机可以通过电子信号来控制其精确的位置和速度。它具有体积小、重量轻、响应快等特点,因此在各种小型机械…...

【4.13(补)】二叉搜索树的遍历、插入、删除

文章目录二叉搜索树的最近公共祖先二叉搜索树中的插入操作删除二叉搜索树中的节点二叉搜索树的最近公共祖先 235. 二叉搜索树的最近公共祖先 - 力扣(LeetCode) 因为二叉搜索树是有序的,第一次找到p和q中间的值,就是最近的公共祖先…...

Web 攻防之业务安全:Callback自定义测试(触发XSS漏洞)

Web 攻防之业务安全:Callback自定义测试 业务安全是指保护业务系统免受安全威胁的措施或手段。广义的业务安全应包括业务运行的软硬件平台(操作系统、数据库,中间件等)、业务系统自身(软件或设备)、业务所提…...

Java访问底层操作系统

native方法定义: 简单地讲,一个Native Method就是一个java调用非java代码的接口。一个Native Method是这样一个java的方法:该方法的实现由非java语言实现,比如C。这个特征并非java所特有,很多其它的编程语言都有这一机…...

Python 进阶指南(编程轻松进阶):十六、面向对象编程和继承

原文:http://inventwithpython.com/beyond/chapter16.html 定义一个函数,并从几个地方调用它,可以省去复制和粘贴源代码的麻烦。不复制代码是一个很好的实践,因为如果你需要修改它(无论是为了修复一个错误还是添加新特…...

【计算机系统结构】第一章 计算机系统结构基本概念

文章目录第一章 计算机系统结构基本概念1.1 计算机系统结构的概念1.2 计算机体系结构的发展1.3 系统结构中并行性的发展1.4 系统结构的设计1.5 定量分析技术基础第一章 计算机系统结构基本概念 课程内容 A I P S N 工业革命 1.1 计算机系统结构的概念 引言 第一台通用计算机 …...

e2fsprogs logsave Ubuntu 安装失败 unable to make backup link of ‘./usr/bin/chattr‘

最近给服务器从 Ubuntu 18.04 LTS 升级到 20.04 LTS,过程中崩溃,重新尝试执行,提示依赖错误。这时候 apt install 所有的东西都会报错,提示依赖不满足。(这里的报错忘了复制了)执行 apt upgrade 也是一样。…...

在排序数组中查找元素的第一个和最后一个位置(二分查找进阶)

在写这个题目之前需要大家自行看一下我之前写的博客有关二分查找思想,如何判断什么时候使用二分查找以及边界值的确定:二分查找思想力扣实例_徐憨憨!的博客-CSDN博客 题目:给你一个按照非递减顺序排列的整数数组 nums,和一个目标值 target。请你找出给定…...

1 Nginx跨域配置

跨域问题在之前的单体架构开发中,其实是比较少见的问题,除非是需要接入第三方SDK时,才需要处理此问题。但随着现在前后端分离、分布式架构的流行,跨域问题也成为了每个Java开发必须要懂得解决的一个问题。 跨域问题产生的原因 产…...

ChatGTP如此强大,我们普通人如何利用它来赚钱?

我从效率提升的角度,分享了我这段时间看到的、用到的,以及思考的一些内容。 最近这段时间,我算是密集的学习。不得不说,优质的资料在推特和油管上特别多,看科技大佬的分享真是一种享受。 很多大神也会录制各种详细的…...

常见的九种大数据分析模型

常见的9种大数据分析模型分别为: 事件分析、 属性分析、 渠道分析、 Session分析、 留存分析、 归因分析、 漏斗分析、 路径分析、 分布分析 1、【事件分析】 事件分析,是指用户在 APP、网站等应用上发生的行为,即何人,何时&…...

射频识别(RFID)技术的基本原理、特性、发展和应用

何谓射频识别 随着高科技的蓬勃发展,智能化管理已经走进了人们的社会生活,一些门禁卡、第二代身份证、公交卡、超市的物品标签等,这些卡片正在改变人们的生活方式。其实秘密就在这些卡片都使用了射频识别技术,可以说射频识别已成…...

3.3 二维随机变量条件分布

学习目标: 要学习二维随机变量的条件分布,我可能会采取以下步骤: 复习边缘分布和联合分布:首先需要了解二维随机变量的边缘分布和联合分布的概念以及相应的公式。 复习条件概率:学习条件概率的定义和计算公式&#x…...

Kafka——概述、安装及命令行操作

文章目录一、概述1.1、定义1.2、如何运作?1.3、传统消息队列的应用场景1.4、消息队列的两种模式1.5、Kafka的基础架构二、安装(需要安装zookeeper)三、常用命令行操作3.1、主题命令行操作3.2、生产者命令行操作3.3、消费者命令行操作一、概述…...

怎么控制ERP企业管理系统开发的价格

企业资源规划(ERP)是一种广泛使用的商业软件系统,用于管理企业的各个方面,包括财务、供应链、客户关系、人力资源等等。开发一个适合企业的ERP系统可能是一项昂贵的任务,但控制ERP企业管理系统开发的价格是可行的。以下…...

python打卡day49

知识点回顾: 通道注意力模块复习空间注意力模块CBAM的定义 作业:尝试对今天的模型检查参数数目,并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...

从WWDC看苹果产品发展的规律

WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...

【网络安全产品大调研系列】2. 体验漏洞扫描

前言 2023 年漏洞扫描服务市场规模预计为 3.06(十亿美元)。漏洞扫描服务市场行业预计将从 2024 年的 3.48(十亿美元)增长到 2032 年的 9.54(十亿美元)。预测期内漏洞扫描服务市场 CAGR(增长率&…...

Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)

目录 1.TCP的连接管理机制(1)三次握手①握手过程②对握手过程的理解 (2)四次挥手(3)握手和挥手的触发(4)状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...

2024年赣州旅游投资集团社会招聘笔试真

2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...

【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】

1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件(System Property Definition File),用于声明和管理 Bluetooth 模块相…...

图表类系列各种样式PPT模版分享

图标图表系列PPT模版,柱状图PPT模版,线状图PPT模版,折线图PPT模版,饼状图PPT模版,雷达图PPT模版,树状图PPT模版 图表类系列各种样式PPT模版分享:图表系列PPT模板https://pan.quark.cn/s/20d40aa…...

LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》

这段 Python 代码是一个完整的 知识库数据库操作模块,用于对本地知识库系统中的知识库进行增删改查(CRUD)操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 📘 一、整体功能概述 该模块…...

JavaScript基础-API 和 Web API

在学习JavaScript的过程中,理解API(应用程序接口)和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能,使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...

【JavaSE】多线程基础学习笔记

多线程基础 -线程相关概念 程序(Program) 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序,比如我们使用QQ,就启动了一个进程,操作系统就会为该进程分配内存…...