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

线程安全(二)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 

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 精通Postman响应解析:正则表达式的实战应用
  • LangChain与GraphQL:开启API开发的新篇章
  • 安防监控视频平台LntonCVS视频融合共享平台智慧消防实现远程集中视频监控方案
  • 面试问题梳理:项目中防止配置中的密码泄露-Jasypt
  • DNS缓存详解
  • headerpwn:一款针对服务器响应与HTTP Header的模糊测试工具
  • 优化实战篇—自关联的优化
  • 《昇思25天学习打卡营第05天|qingyun201003》
  • debian固定ip
  • c++ :运算符重载函数中的细节
  • jmeter-beanshell学习9-放弃beanshell
  • k8s快速部署一个网站
  • tkinter-TinUI-xml实战(11)多功能TinUIxml编辑器
  • 【python学习】python标准库之正则表达式库re的定义、功能和函数,以及正则表达式的元字符和含义
  • 【深度学习入门篇 ②】Pytorch完成线性回归!
  • 【node学习】协程
  • CNN 在图像分割中的简史:从 R-CNN 到 Mask R-CNN
  • es6(二):字符串的扩展
  • k个最大的数及变种小结
  • Linux中的硬链接与软链接
  • PHP CLI应用的调试原理
  • Python_网络编程
  • Vue UI框架库开发介绍
  • WePY 在小程序性能调优上做出的探究
  • -- 查询加强-- 使用如何where子句进行筛选,% _ like的使用
  • 成为一名优秀的Developer的书单
  • 模型微调
  • 区块链将重新定义世界
  • 如何邀请好友注册您的网站(模拟百度网盘)
  • 详解NodeJs流之一
  • 再次简单明了总结flex布局,一看就懂...
  • 格斗健身潮牌24KiCK获近千万Pre-A轮融资,用户留存高达9个月 ...
  • ​​​​​​​开发面试“八股文”:助力还是阻力?
  • ​一文看懂数据清洗:缺失值、异常值和重复值的处理
  • #pragma once与条件编译
  • $con= MySQL有关填空题_2015年计算机二级考试《MySQL》提高练习题(10)
  • $forceUpdate()函数
  • (007)XHTML文档之标题——h1~h6
  • (1) caustics\
  • (4)事件处理——(7)简单事件(Simple events)
  • (LeetCode C++)盛最多水的容器
  • (补充)IDEA项目结构
  • (草履虫都可以看懂的)PyQt子窗口向主窗口传递参数,主窗口接收子窗口信号、参数。
  • (附源码)ssm教师工作量核算统计系统 毕业设计 162307
  • (七)Java对象在Hibernate持久化层的状态
  • (原)Matlab的svmtrain和svmclassify
  • (转)自己动手搭建Nginx+memcache+xdebug+php运行环境绿色版 For windows版
  • .NET CF命令行调试器MDbg入门(一)
  • .Net CoreRabbitMQ消息存储可靠机制
  • .NET Entity FrameWork 总结 ,在项目中用处个人感觉不大。适合初级用用,不涉及到与数据库通信。
  • .NET 程序如何获取图片的宽高(框架自带多种方法的不同性能)
  • .NET:自动将请求参数绑定到ASPX、ASHX和MVC(菜鸟必看)
  • .NET精简框架的“无法找到资源程序集”异常释疑
  • .NET之C#编程:懒汉模式的终结,单例模式的正确打开方式
  • @param注解什么意思_9000字,通俗易懂的讲解下Java注解