java 多线程()—— 线程同步=队列+锁

news2024/11/17 1:39:48

一、线程同步 = 队列 + 锁

同步就是多个线程同时访问一个资源。

那么如何实现? 队列+锁。

想要访问同一资源的线程排成一个队列,按照排队的顺序访问。访问的时候加上一个锁(参考卫生巾排队+锁门),访问完释放锁。

二、 不安全案例

2.1 不安全的抢票系统

之前我们实现过这个例子。

package Unsafe;

public class RailwayTicketSystem{

    public static void main(String[] args) {
        BuyTicket buyer = new BuyTicket();
        new Thread(buyer,"黑黑").start();
        new Thread(buyer,"白白").start();
        new Thread(buyer,"黄牛党").start();
    }
}

class BuyTicket implements Runnable{
    private int ticketNums = 10;  //系统里有10张票

    //抢票行为
    @Override
    public void run() {
        while(ticketNums>0){
            try {
                Thread.sleep(100);  //模拟延时,放大问题的发生性
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"--->抢到了第"+ticketNums+"张票");
            ticketNums--;
        }
    }
}

2.2 不安全的银行取钱 

场景: 黑土有一张存款为100万的卡,黑土去银行柜台取钱50万,同一时刻,黑土的老婆白云也要通过网上银行从卡里取走100万。

因为取钱是用户各自取各自账户里的钱,不存在多个线程操作同一个对象(所有用户都去抢系统里的票),所以可以用extends Thread。

but why?

package Unsafe;

public class UnsafeBank {
    public static void main(String[] args) {
        //黑黑的卡里一共有100万
        Account  黑土的卡 = new Account("黑土的卡",100);

        //黑黑要从卡里取走50万
        DrawMoney 黑土 = new DrawMoney(黑土的卡,50);
        黑土.start();
        //同时,白白也来到了银行,白白要从卡里取走100万
        DrawMoney 白云 = new DrawMoney(黑土的卡, 100);
        白云.start();
    }
}


//银行卡
class Account{
    private String name; //持卡人
    private int money ; //余额

    public Account(String name, int money) {
        this.name = name;
        this.money = money;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getMoney() {
        return money;
    }

    public void setMoney(int money) {
        this.money = money;
    }
}

//银行:模拟取款
class DrawMoney extends Thread{
    Account account; //账户
    int drawMoney; //要取多少钱
    public DrawMoney(Account account,int drawMoney){
        this.account = account;
        this.drawMoney = drawMoney;
    }

    //取钱
    @Override
    public void run() {
        if(account.getMoney()-drawMoney<0){
            System.out.println("余额已不足,【"+Thread.currentThread().getName()+"】无法取钱");
            return;
        }

        //延时,放大问题的发生
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        //余额变动
        account.setMoney(account.getMoney() - drawMoney);
        System.out.println(Thread.currentThread().getName()+"取走了"+drawMoney);
        //输出余额
        System.out.println(account.getMoney());
    }
}

2.3 不安全的集合

这里以ArraryList为例,我们知道ArraryList的底层是用数组存储的。当多个线程同时执行add方法时,会出现多个线程向数组的同一个位置存放数据的情况。

        

三、同步机制

由于我们可以用private关键字来保证数据只能被方法访问,所以我们只需要针对类似于getXX()方法提出一套机制,这套机制就是synchronized关键字。它包括两种用法

1. synchronized方法

2. synchronized块

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

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

相关文章

gitblit 搭建本地 git 仓库

目录 一、简介 二、准备工作 1.安装Java 2.下载gitblit 3.创建资料目录 三、修改配置 1.git.repositoriesFolder 2.server.httpPort 3.server.httpBindInterface 4.installService.cmd 四、gitblit图标显示异常 结束 一、简介 Gitblit是一个用于管理&#xff0c;查…

数据结构与算法这么重要还不会?字节内部笔记来帮你轻松拿下!

对任何专业技术人员来说&#xff0c;理解数据结构都非常重要。作为软件开发者&#xff0c;我们要能够用编程语言和数据结构来解决问题。编程语言和数据结构是这些问题解决方案中不可或缺的一部分。如果选择了不恰当的数据结构&#xff0c;可能会影响所写程序的性能。因此&#…

VKL076-19*4点 超低功耗抗干扰LCD液晶段码显示屏驱动控制电路(IC/芯片),超低工作电流约7.5微安,多用于仪器仪表类,可提供FAE技术支持

产品品牌&#xff1a;永嘉微电/VINKA 产品型号&#xff1a;VKL076 封装形式&#xff1a;SSOP28 概述&#xff1a; VKL076 SSOP28是一个点阵式存储映射的LCD驱动器&#xff0c;可支持最大76点&#xff08;19SEGx4COM&#xff09;的 LCD屏。单片机可通过I2C接口配置显示参数和…

【Hack The Box】linux练习-- SwagShop

HTB 学习笔记 【Hack The Box】linux练习-- SwagShop &#x1f525;系列专栏&#xff1a;Hack The Box &#x1f389;欢迎关注&#x1f50e;点赞&#x1f44d;收藏⭐️留言&#x1f4dd; &#x1f4c6;首发时间&#xff1a;&#x1f334;2022年11月17日&#x1f334; &#x1…

Python 完美解决 Import “模块“ could not be resolved ...

vscode 中 python 提示警告错误&#xff0c;但是还是能跑起来代码&#xff1a; Import "playwright.sync_api" could not be resolved Pylance reportMissingImports 原因可能有两个&#xff1a; 1、未下载此包&#xff0c;打开命令行&#xff0c;输入 $ pip list&a…

problem B.Genshin Impact(2022合肥icpc)

题意&#xff1a;对目标持续施法&#xff0c;法术是每隔y秒让目标开始持续燃烧x秒&#xff0c;每次施法的概率是1/p 求燃烧时间比上总时间的期望值 &#xff08;题面是laji&#xff09; 思路&#xff1a;我们把总时间看成许多y段 当x<y的时候&#xff0c;只有一种情况就…

JVM虚拟机(整体架构、类文件结构)我来了~~~

虚拟机 1.1 发展历程 1.1.1 java往事 ​ Java诞生在一群懒惰、急躁而傲慢的程序天才之中。 ​ 1990年12月&#xff0c;Sun的工程师Patrick Naughton被当时糟糕的Sun C工具折磨的快疯了。他大声抱怨&#xff0c;并威胁要离开Sun转投当时在Steve Jobs领导之下的NeXT公司。领导…

CRGDFPASSC,CAS号:166184-23-2

CRGDFPASSC是一种含环rgd的十肽&#xff0c;与血小板表面的纤维蛋白原受体结合。在5号位置用Phe取代Ser的类似物作为血小板聚集抑制剂&#xff0c;其活性是CRGDSPASSC的3倍(IC₅₀ 2.5M)。 编号: 130659中文名称: CRGDFPASSC英文名: CRGDFPASSCCAS号: 166184-23-2单字母: CRGDF…

方法2—并行数据流转换为一种特殊串行数据流模块的设计,

并行数据流转换为一种特殊串行数据流模块的设计&#xff0c;设计两个可综合的电路模块1&#xff0c;第一个可综合模块&#xff0c;M1。2&#xff0c;描述M2模块3&#xff0c;描述M0模块的Verilog代码4&#xff0c;描述顶层模块5&#xff0c;电路生成的门级网表&#xff0c;netl…

【第五部分 | JS WebAPI】1:WebAPIs概述、网页元素的获取、事件

目录 | 概述 | 文档、元素、节点的概念 | 获取元素 根据ID获取 根据标签名获取 通过HTML5新增方法获取 特殊元素获取&#xff08;body html&#xff09; | 事件基础 事件三要素 点击事件 光标获得/失去焦点事件 [ 更多其它事件 ] 刷新网页自动执行某些事件 | 概述 …

Alibaba内部首发“面试百宝书+超全算法面试手册”PDF版下载

面试你打算要多高的薪资&#xff1f; 第一份工作的薪资水平就是你的薪资起点&#xff0c;如果你拿到的第一份薪水远高于其他人&#xff0c;那么你在未来涨薪路上就会省很多力。 想刚开始工作就拥有高薪&#xff0c;那就需要抬高自己的“身价”&#xff0c;提升自己的工作能力…

[附源码]java毕业设计-线上摄影平台系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

Blob和ArrayBuffer和File

Blob Blob对象表示一个不可变、原始数据的类似文件的对象。Blob 表示的不一定是JavaScript原生格式的数据。 Represents a “Binary Large Object”, meaning a file-like object of immutable, raw data。 type BufferSource ArrayBufferView | ArrayBuffer; type BlobPart…

微前端——single-spa源码学习

前言 本来是想直接去学习下qiankun的源码&#xff0c;但是qiankun是基于single-spa做的二次封装&#xff0c;通过解决了single-spa的一些弊端和不足来帮助大家能更简单、无痛的构建一个生产可用微前端架构系统。 所以我们应该先对single-spa有一个全面的认识和了解&#xff0c…

看了就能懂的NIO使用深入详解

NIO概述 NIO介绍 传统IO流(java.io):读写操作结束前,处于线性阻塞,代码简单,安全,性能低 NIO&#xff1a;支持非阻塞式编程,性能更有优势,但代码编写较为复杂。 概念理解 同步(synchronous):一条线程执行期间,其他线程就只能等待。 异步(asynchronous):一条线程在执行…

Java基础深化和提高-------多线程与并发编程

目录 多线程与并发编程 多线程介绍 什么是程序&#xff1f; 什么是进程? 什么是线程&#xff1f; 进程、线程的区别 什么是并发 线程和方法的执行特点 方法的执行特点 线程的执行特点 什么是主线程以及子线程 主线程 子线程 线程的创建 通过继承Thread类实现多线程 通过Ru…

暴力美学,拒绝平庸,Alibab开源内部神仙级“K8S核心笔记”下载

各大互联网巨头在技术战略层面&#xff0c;都把云原生列为了主要发展方向。以阿里巴巴为例&#xff0c;他们技术老大说&#xff0c;云原生是云计算释放红利的最短路径&#xff0c;也是企业数字化的最短路径。 现在云原生工程师、Kubernetes 工程师工资都特别高&#xff0c;并且…

大厂光环下的功能测试,出去面试自动化一问三不知

在一家公司待久了技术能力反而变弱了&#xff0c;原来的许多知识都会慢慢遗忘&#xff0c;这种情况并不少见。 一个京东员工发帖吐槽&#xff1a;感觉在大厂快待废了&#xff0c;出去面试问自己接口环境搭建、pytest测试框架&#xff0c;自己做点工太久都忘记了。平时用的时候…

【BLE】蓝牙数据速率

【BLE】蓝牙数据速率 理论速度 物理层 未编码PHY&#xff0c;每位数据使用1个符号表示 1Mbps&#xff08;LE 1M PHY&#xff09; 2Mbps&#xff08;LE 2M PHY&#xff09; 编码PHY 500Kbps&#xff08;S2&#xff09; 125Kbps&#xff08;S8&#xff09; 1Mbps指的是每…

MATLAB改变默认工作路径

软件版本&#xff1a;MATLAB2022a 电脑系统&#xff1a;win10 问题&#xff1a; 每次打开matlab都会自动打开matlab.exe文件夹位置&#xff0c;而不是打开自己新建的工作空间每次都要转换&#xff0c;很麻烦 方法&#xff1a; 1、找到安装目录下的matlabrc.m文件&#xff0…