Spring Boot 中的 synchronized(this):到底锁住了谁?
“锁住自己,还得看看你是不是全公司唯一一份。” 在 Java 里,synchronized(this) 代表锁住当前对象。在单线程环境下这很好理解,但一旦进入 Spring Boot 多线程并发的世界,很多人就开始困惑了: “我这个接口加了 synchronized(this),为啥还是串行执行?或者为啥根本没锁住?” 今天,我们就以最接地气的 Spring Boot 接口请求为例,彻底讲清楚 this 在 Bean 中到底锁的是谁、对谁生效、什么场景会起作用。 一、this 是谁?在 Java 中,this 是当前对象的引用。 1234567public class Person { String name; public void introduce() { System.out.println("我叫 " + this.name); }} 没错,this 指向的是当前对象。不同的对象就有不同的 this。 你可以把 this 理解成对象界的身份证,一个对象一个号,不能复印...
Spring Boot 3 + Kafka 实战指南
——麻辣火锅版 🍲 1. 项目层级像火锅店的分工:点单员、传菜员、食客清清楚楚。 12345678910111213141516kafka/├── pom.xml # 根 POM(BOM对齐)├── provider/ # 点单:生产者│ ├── pom.xml # 子模块 POM│ └── src/main/java/org/example/provider/│ ├── ProviderApplication.java│ ├── conf/KafkaTopicsConfig.java│ ├── controller/ProviderController.java│ └── service/KafkaProducerService.java│ └── src/main/resources/application.yaml└── consumer/ # 上桌:消费者 ├── pom.xml ...
synchronized的升级过程
synchronized 的升级过程(精简 & 好笑版)一句话总结 synchronized 的锁,会随着竞争程度一路“升职”,但只升不降。 一、synchronized 是干嘛的?很简单:👉 保证同一时刻,只有一个线程能干活👉 顺便还送你一张 happens-before 的内存可见性门票 本质上,它就是在用 对象自带的监视器锁(Monitor)。 二、锁升级路线图(主线剧情)1无锁 → 偏向锁(已退休) → 轻量级锁 → 重量级锁 记住一句话就够了: 竞争越激烈,锁越“重”。 三、四种锁,用一句话讲清楚1️⃣ 无锁:世界很和平 没人抢,直接用 性能最好 对象头里就是普通信息 🧘:“今天没人吵架。” 2️⃣ 偏向锁:对象只爱一个线程(已退役) 第一次用锁的线程,被对象“记住” 后面再来,连 CAS 都懒得做 Java 15+ 默认禁用,已弃用 💔:“曾经专一,现在分手。” 3️⃣ 轻量级锁:礼貌地抢 多线程来了,但不算多 用 CAS + 自旋 运行在 用户态(Ring 3) 不阻塞,先忙等一会儿 🤺:“我先转几圈看看你放不放手。” 4...
《写给 Java 程序员的七大设计原则全解析:别让你的代码变成意大利面》🍝
“代码如诗,架构如歌。设计原则,便是那不走调的节拍。” 🎯 前言:什么是设计原则?在软件开发的世界里,我们追求的是高内聚、低耦合、可维护、易扩展。而设计原则就是那一把衡量代码质量的“戒尺”,帮助我们写出健壮、优雅的代码。 今天我们就来聊聊——面向对象的七大设计原则,每一条我都会配上一个小例子,助你理解记忆。 🧱 一、单一职责原则(SRP)✨ 定义: 一个类只负责一项职责。 “只做一件事,并做好它。” 🧩 举个栗子:class Report { public void generate() { System.out.println("生成报表内容"); } public void print() { System.out.println("打印报表"); } public void sendEmail() { System.out.println("发送报表邮件...
江湖险恶:ReadWriteLock 与 ReentrantLock 的爱恨情仇
话说在Java的江湖上,有两大门派闻名遐迩,一个叫ReentrantLock(可重入锁) ,一个叫ReadWriteLock(读写锁) 。 江湖人称:一个讲究「一夫当关,万夫莫开」,一个讲究「以和为贵,能读就别写」。 今天我们就来揭开它们的面纱,聊聊它们的区别、用法、场景,顺便插科打诨,轻松一下。 【一】人物介绍 锁派 简介 主要技能 适用场景 ReentrantLock 可重入锁,一把锁走天下 支持公平锁/非公平锁、可中断、超时、Condition 读多写多、竞争激烈 ReadWriteLock 读写分离,善于协调 读多写少,提升并发性 典型读多写少场景 【二】ReentrantLock:霸道总裁,万事亲力亲为ReentrantLock 是个「霸道总裁」,不分青红皂白,谁进来都要排队。就算只是读个数,也得等别人写完。效率?它不太关心。 12345678910ReentrantLock lock = new ReentrantLock();public void doSomething() { lock.lock(); try...
别慌,Java只有值传递——一次搞懂“为啥我改了它还不变”!
亲爱的程序员兄弟姐妹们: 是不是有那么一瞬间,你写着写着代码,突然怀疑人生: int a = 1; int b = a; a = 2; System.out.println(b); // 结果是1,没变! User user = new User("张三"); User user1 = user; user = new User("李四"); System.out.println(user1.getName()); // 结果还是张三,没变! 这是不是耍我? 别慌,今天咱们用箱子和标签这个有趣的比喻,帮你一次性搞清楚! 一、Java的铁律:只有值传递!无论是: 基本数据类型(int、double、char…) 引用数据类型(对象、数组、集合…) Java 永远都是值传递。 二、基本数据类型:值传递——我拿的是实物int a = 1; int b = a; a = 2; System.out.println(b); // 输出1 这里的 a 和 b 像是两个独立的小箱子。 开始时,你把 1 这个“苹果”放到了两个箱子里。...
MySQL 中的快照读与当前读:原理、区别与应用详解(幽默版)
MySQL 中的快照读与当前读:一场并发江湖的武林较量在 MySQL 的江湖里,有两位著名的“读”法门——快照读(Snapshot Read) 与 当前读(Current Read) ,一个主打“隐身术”,一个擅长“当面打”。他们虽同为读取数据,却走着完全不同的修炼路线。 今天我们就来围观这两位大侠是如何在事务高并发的武林中各显神通的。 tips:相对应的专业版本请看上篇文章:https://juejin.cn/post/7498769310833803298 🎯 开篇三大心法(你得背下来) ✅ 当前读就像“看到别人刚刚擦干净的桌子”——总是读到最新别人已提交的数据。 ✅ 幻读是数据库界的“灵异事件”,只有当前读才能用锁链把幽灵锁住。 ✅ LOCK IN SHARE MODE 就像温文尔雅的绅士:“我不改,但你们也别想偷偷动!” 一、概念篇:你是谁?你从哪来?🥷 快照读(Snapshot Read) 修炼路线:MVCC(多版本并发控制) 绝招:我读的是我刚进门那一刻看到的数据,别人后来改了?无感! 特点:轻功好,不加锁,速度快,但容易被幻觉迷惑 1SELECT *...
MySQL中INT数据类型的括号、ZEROFILL和UNSIGNED关键字大揭秘!
引言:INT的“魔法数字”世界在MySQL里,INT是存储整数的“超级英雄”,但它身后跟着的括号(比如INT(11))、ZEROFILL和UNSIGNED关键字却让不少人摸不着头脑。括号里的数字到底是干嘛的?ZEROFILL为啥要把数字前面塞满0?UNSIGNED又是个啥?别急!本文会用可爱又生动的语言,搭配一堆示例和表格,带你把这些“魔法”弄得清清楚楚! 1. 括号里的数字:显示宽度or存储范围?当你定义一个MySQL表时,可能会看到这样的代码: 1234CREATE TABLE users ( id INT, age INT(2)); INT后面那个(2)是啥意思?很多小伙伴以为它限制了数字的大小,比如INT(2)只能存2位数(0到99)。但真相是:括号里的数字只影响显示宽度,不影响存储范围! 1.1 显示宽度是啥?显示宽度(M)告诉MySQL在某些情况下(比如配合ZEROFILL)如何“美化”数字的显示。它不限制能存多大的数字,INT的存储范围永远由它的类型决定: 有符号INT(默认):-2,147,483,648 到 2,147,483,647(32位,4...
MySQL中三层B+树索引的数据存储容量解析
在MySQL的InnoDB存储引擎中,B+树作为核心数据结构支撑着索引系统。理解其存储容量对于数据库设计和性能优化至关重要。本文将通过结构解析和数学推导,揭示三层B+树在典型配置下的数据承载能力。 一、B+树结构特性B+树由根节点、内部节点和叶子节点构成三层结构: 根节点:索引入口点,存储指向内部节点的指针 内部节点:作为路由层,存储键值和子节点指针 叶子节点:最终数据容器,存储实际数据记录或主键指针 每个节点大小由InnoDB页大小决定,默认配置为16KB(16384字节)。这种分层结构通过减少磁盘I/O次数实现高效查询。 二、存储容量计算公式数据存储量计算公式:总记录数 ≈ (每页指针数)^(树高度-1) × 每叶子页记录数 1. 内部节点指针数计算假设主键为BIGINT类型(8字节),指针占6字节: 12345每页指针数 = 页面大小 / (键值大小 + 指针大小) = 16384 / (8 + 6) ≈ 1170 个指针/页 2. 叶子节点记录数计算假设单条记录1KB: 12345每页记录数 = 页面大小 / 单条记录大...
SQL中JOIN操作的条件使用总结与最佳实践
在SQL查询中,JOIN操作是多表关联的核心工具,而条件的使用位置(ON vs WHERE)直接影响查询结果和性能。本文从原理、场景和最佳实践三个方面总结JOIN条件的使用规则,帮助开发者精准控制查询逻辑。 一、ON与WHERE的本质区别 执行顺序 ON条件:在连接(JOIN)操作时立即生效,用于确定两表如何匹配,生成临时结果集。 WHERE条件:在连接完成后对结果集进行过滤,作用于最终数据。 对结果集的影响 INNER JOIN:ON和WHERE效果相同,均过滤未匹配记录。 LEFT JOIN/RIGHT JOIN: ON条件仅影响关联表的匹配,保留主表所有记录。 WHERE条件会过滤整个结果集,可能导致主表记录丢失(如外连接时)。 FULL OUTER JOIN:ON控制匹配逻辑,WHERE进一步筛选结果。 二、场景化条件使用规则 JOIN类型 条件放在ON中 条件放在WHERE中 INNER JOIN 正确:过滤未匹配记录 正确:效果同ON,但语义较弱 LEFT JOIN 正确:保留左表全部记录,右表按需匹配 风险:可能过...













