线程安全(二)synchronized 的底层实现原理、锁升级、对象的内存结构

目录

    • 一、基础使用
      • 1.1 不加锁的代码实现
      • 1.2 加锁的代码实现
    • 二、实现原理
      • 2.1 synchronized 简介
      • 2.2 对象监控器(Monitor)
      • 2.3 加锁过程
        • 第一步:判断 Owner 指向
        • 第二步:进入 EntryList 阻塞
        • 第三步:主动进入 WaitSet 等待
    • 三、锁升级
      • 3.1 对象的内存结构
      • 3.2 Mark Word 对象头
      • 3.3 Monitor 重量级锁
      • 3.4 轻量级锁
        • 1)背景:
        • 2)加锁过程:
        • 3)解锁过程:
      • 3.5 偏向锁
        • 1)背景:
        • 2)加锁过程:
        • 3)轻量级锁 vs 偏向锁
      • 3.6 总结

一、基础使用

  • 假如有这样一个场景:20个用户一起抢10张票

1.1 不加锁的代码实现

public class TicketDemo {
   

    // 票总数
    private int ticketNum = 10;

    /**
     * 抢票
     */
    public void getTicket() {
   
        if (ticketNum <= 0) {
   
            return;
        }
        System.out.println(Thread.currentThread().getName() + " 抢到一张票,剩余:" + ticketNum);
        // 非原子性操作
        ticketNum--;
    }

    /**
     * 测试:20个人抢一张票
     */
    public static void main(String[] args) {
   
        TicketDemo ticketDemo = new TicketDemo();
        for (int i = 0; i < 20; i++) {
   
            new Thread(ticketDemo::getTicket).start();
        }
    }
}

执行结果:

可以看到出现了 超卖问题,一共10张票,当20个线程一起抢票就出现有11个人抢到了票。这是因为如果两个线程同时通过了 if 校验。

所以我们需要对票数的操作进行加锁,保证同一时间只有一个线程来检查和操作票数扣减。

1.2 加锁的代码实现

public class TicketDemo {
   

    // 锁
    private static Object lock = new Object();

    // 票总数
    private int ticketNum = 10;

    /**
     * 抢票
     */
    public void getTicket() {
   
        synchronized (lock) {
   
            if 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

全方位指南,电子期刊制作入门到精通

在这个数字化时代&#xff0c;电子期刊作为一种新兴的媒体形式&#xff0c;以其方便快捷、互动性强、传播范围广等特点&#xff0c;受到越来越多人的青睐。那么&#xff0c;如何制作出一本既专业又有吸引力的电子期刊呢&#xff1f; 一、选择合适的制作软件 首先&#xff0c;选…

Docker 使用基础(7)—Dockerfile

​ &#x1f3ac;慕斯主页&#xff1a;修仙—别有洞天 ♈️今日夜电波&#xff1a;秒針を噛む—ずっと真夜中でいいのに。 0:34━━━━━━️&#x1f49f;──────── 4:20 &#x1f504; ◀️ ⏸…

Pod网络、Service网络、网络插件Calico、网络插件Flannel(2024-07-12)

一、Pod网络 在K8S集群里&#xff0c;多个节点上的Pod相互通信&#xff0c;要通过网络插件来完成&#xff0c;比如Calico网络插件。 使用kubeadm初始化K8S集群时&#xff0c;有指定一个参数 --pod-networkcidr10.18.0.0/16 它用来定义Pod的网段。而我们在配置Calico的时候&…

视频号矩阵系统源码,实现AI自动生成文案和自动回复私信评论,支持多个短视频平台

在当今短视频蓬勃发展的时代&#xff0c;视频号矩阵系统源码成为了自媒体人争相探索的宝藏。这一强大的技术工具不仅能帮助我们高效管理多个短视频平台&#xff0c;更能通过AI智能生成文案和自动回复私信评论&#xff0c;为自媒体运营带来前所未有的便利与效率。 一、视频号矩…

【排序算法】—— 归并排序

归并排序时间复杂度O(NlongN)&#xff0c;空间复杂度O(N)&#xff0c;是一种稳定的排序&#xff0c;其次可以用来做外排序算法&#xff0c;即对磁盘(文件)上的数据进行排序。 目录 一、有序数组排序 二、排序思路 三、递归实现 四、非递归实现 一、有序数组排序 要理解归…

unity3d脚本使用start,updata,awake

最近学了一下unity&#xff0c;脚本编写用的c#&#xff0c;虽说没学过c#但是勉强根据教学还能写点代码。 在这里我来记录一下在我学习过程中感觉最重要的东西 消息函数&#xff1a; 在我们创建一个脚本文件的时候&#xff0c;我们首先可以看到两个默认给你写出来的函数。 这两…

昇思25天学习打卡营第21天|应用实践之GAN图像生成

基本介绍 今日要实践的模型是GAN&#xff0c;用于图像生成。使用的MNIST手写数字数据集&#xff0c;共有70000张手写数字图片&#xff0c;包含60000张训练样本和10000张测试样本&#xff0c;数字图片为二进制文件&#xff0c;图片大小为28*28&#xff0c;单通道&#xff0c;图片…

Redislnsight-v2远程连接redis

redis安装内容添加&#xff1a; Linux 下使用Docker安装redis-CSDN博客 点击添加 添加ip地址&#xff0c;密码&#xff0c;端口号 创建完成 点击查看内容&#xff1a;

CAN总线学习

can主要用于汽车、航空等控制行业&#xff0c;是一种串行异步通信方式&#xff0c;因为其相较于其他通信方式抗干扰能力更强&#xff0c;更加稳定。原因在于CAN不像其他通信方式那样&#xff0c;以高电平代表1&#xff0c;以低电平代表0&#xff0c;而是通过电压差来表示逻辑10…

ESP32CAM人工智能教学13

ESP32CAM人工智能教学13 openCV 安装 小智发现openCV是一款非常出色的机器视觉软件&#xff0c;可以配合ESP32Cam的摄像头&#xff0c;开发出许许多多的人工智能应用情境。 下载视频服务驱动库 OpenCV是开源的计算机视觉驱动库&#xff0c;可以应用于机器人的图形处理、机器学…

JDK,JRE,JVM三者之间的关系

Java程序不是直接在操作系统之上运行&#xff0c;而是运行在JVM&#xff08;java虚拟机&#xff09;之上。 Java源代码&#xff08;.java文件&#xff09;经编译器编译成字节码&#xff08;.class文件&#xff09;&#xff0c;JVM本质上就是一个负责解释执行Java字节码的程序。…

旷野之间20 - Google 研究的推测 RAG

为什么选择 RAG 新兴能力 直到最近&#xff0c;人们发现 LLM 具有新兴能力&#xff0c;即在与用户或任务交互过程中出现的意外功能。 这些功能的示例包括&#xff1a; 解决问题&#xff1a; LLM 可以利用其语言理解和推理能力&#xff0c;为未经过明确培训的任务提供富有洞…

Unity UGUI Image Maskable

在Unity的UGUI系统中&#xff0c;Maskable属性用于控制UI元素是否受到父级遮罩组件的影响。以下是关于这个属性的详细说明和如何使用&#xff1a; Maskable属性 Maskable属性&#xff1a; 当你在GameObject上添加一个Image组件&#xff08;比如UI面板或按钮&#xff09;时&…

网络请求优化:如何让你的API飞起来

网络请求优化&#xff1a;如何让你的API飞起来 亲爱的开发者朋友们&#xff0c;你是否曾经遇到过这样的场景:用户疯狂点击刷新按钮,你的服务器却像老年人散步一样慢吞吞地响应。或者,你的应用像个贪吃蛇,疯狂吞噬用户的流量包。如果你对这些情况再熟悉不过,那么恭喜你,你正需要…

Redis分布式锁-Redisson可重入锁原理的个人见解。

记录Redisson可重入锁的个人见解。 文章目录 前言一、什么叫做锁的重入&#xff1f;二、Redisson可重入锁原理 前言 ⁣⁣⁣⁣ ⁣⁣⁣⁣ 之前在写项目的时候&#xff0c;注意到Redisson可重入锁的一个问题&#xff0c;随即在网上搜索其对应的资料&#xff0c;下面就记录一下个…

AI发展下的伦理挑战,应当如何应对?

引言 人工智能&#xff08;AI&#xff09;技术的迅猛发展给我们带来了前所未有的便利和创新&#xff0c;但也伴随着一系列复杂的伦理挑战。从侵犯数据隐私到制造“信息茧房”&#xff0c;AI的应用在许多方面都引发了伦理和社会问题。随着AI技术逐渐渗透到社会各个领域&#xf…

C双指针元素去重

需求 在尾部插⼊、删除元素是⽐较⾼效的&#xff0c;时间复杂度 是 O(1)&#xff0c;但是如果在中间或者开头插⼊、删除元素&#xff0c;就会涉及数据的搬移&#xff0c;时间复杂度为 O(N)&#xff0c;效率较低。 代码 #include <stdio.h>// 相邻元素去重 int remove…

3d复制的模型怎么渲染不出来?----模大狮模型网

在展览3D模型设计领域&#xff0c;技术的进步和创新使得模型的复杂性和精细度有了显著提升。然而&#xff0c;有时设计师们在尝试渲染复杂的3D复制模型时&#xff0c;却面临着无法正确呈现的问题。模大狮将探讨这一现象的可能原因&#xff0c;并提供相应的解决方案和建议&#…

最值得推荐的10款Windows软件!

AI视频生成&#xff1a;小说文案智能分镜智能识别角色和场景批量Ai绘图自动配音添加音乐一键合成视频播放量破百万https://aitools.jurilu.com/1.音乐播放器——Dopamine Dopamine是一款音乐播放器&#xff0c;设计简洁美观。它支持多种音频格式&#xff0c;包括wav、mp3、ogg…

Maven学习笔记——如何在pom.xml中通过坐标为项目导入jar包

注意&#xff1a;我们只导入了一个jar包坐标&#xff0c;但右边项目中确多出来了好几个jar包&#xff0c;这是因为我们导入的该jar包所依赖其他jar包&#xff0c;maven自动帮我们导入了进来