- 博客(85)
- 收藏
- 关注
原创 Java并发变成进阶:ConcurrentHashMap底层原理深度拆解
集合框架是Java开发中很常用的框架,单线程下没什么问题,但是多线程下有很大的并发问题数据覆盖数据丢失扩容死循环(JDK7)因为 HashMap 本身没有任何同步机制,多线程下会有很大的并发安全问题全局元素数量 + 1检查元素总数是否超过扩容阈值,达到阈值触发多线程 resize新增元素返回 nullbaseCount + CounterCell = 分段计数避免热点 CAS。
2026-06-25 16:37:26
367
原创 Java并发编程进阶:Semaphore 原理与源码解析
Semaphore(信号量)是 JDK 提供的一个并发工具类,用来控制同时访问某个资源的线程数量位于:java.util.concurrent.Semaphore例如:Semaphore semaphore = new Semaphore(3);表示:当前资源有3个许可证(Permit)线程1 获取许可证线程2 获取许可证线程3 获取许可证此时许可证耗尽线程4必须等待线程4才能继续执行。
2026-06-23 22:07:26
205
原创 Java 并发编程进阶:ReentrantLock 实现原理详解
在 Java 并发编程中,最常见的加锁方式莫过于 synchronizedsynchronized 使用简单,并且由 JVM 保证锁的获取与释放,是 Java 中最基础的线程同步机制不过随着并发场景越来越复杂,synchronized 的局限性也逐渐显现出来:无法尝试获取锁无法设置获取锁超时时间无法中断等待锁的线程不支持公平锁只能使用单一条件队列。
2026-06-22 21:12:16
401
原创 Java并发编程进阶:彻底理解 AQS 底层原理
AQS(AbstractQueuedSynchronizer)是 JDK 并发包的核心同步框架。整体结构:AQS的设计思想:state负责资源状态获取失败的线程进入队列前驱节点释放资源后唤醒后继节点FIFO保证公平性(公平锁)
2026-06-16 16:48:10
272
原创 JMM 进阶:彻底理解 synchronized 实现原理
是 Java 并发编程中最基础、最重要的线程同步机制之一volatile解决的是(可看前两篇文章)CAS解决的是(可看前两篇文章)解决的是。
2026-06-10 22:12:04
255
原创 JMM 进阶:彻底理解 volatile 实现原理
volatilevolatile 是 Java 轻量级同步关键字,依靠内存屏障实现:保证可见性、禁止特定重排序、不保证原子它只解决多线程并发的可见性、重排序问题,不解决原子性、线程互斥问题volatile本质:1、通过内存屏障禁止特定指令重排序2、通过缓存一致性协议保证可见性3、不保证原子性4、适用于单写多读场景5、DCL单例必须使用volatile现代 CPU 为了提升执行效率,会进行大量优化a = 1;从程序员角度看:先执行 a=1再执行 flag=true。
2026-06-03 20:32:14
369
原创 JVM进阶系列:彻底理解 Java 内存模型(JMM)
目录一、什么是 JMM二、为什么需要 JMM1. CPU缓存导致可见性问题2. 指令重排序导致有序性问题3. 线程切换导致原子性问题4、小结5、JMM的本质三、JMM 的核心抽象模型主内存(Main Memory)工作内存(Working Memory)四、JMM 引发的三大并发问题1. 可见性问题2. 原子性问题3. 有序性问题五、JMM 如何解决这些问题六、Happens-Before 规则七、JMM 的实现手段八、总结JMM(Java Memory Model,Java 内存模型)是 Java 官方定
2026-06-02 21:39:32
413
原创 Java String 全面解析:从源码到常量池,再到面试高频题
"abc" → 常量池new String("abc") → 堆a + b → 堆读取文件/配置/DB → 堆常量池对象 == 常量池对象 → true堆对象 == 常量池对象 → false堆对象 == 堆对象 → false常量池 = 字符串缓存,用来复用对象双引号字面量自动进池new / 拼接 / 读取 → 不进池intern () 手动把堆字符串丢进池。
2026-05-31 22:25:32
436
原创 Java IO流之BIO
可以理解为:数据传输的管道文件 → JVM程序 属于 输入流JVM程序 → 文件 属于 输出流BIO = Blocking I/O 同步阻塞 IO同步:读写操作顺序执行,做完一件才做下一件阻塞:线程调用时,没有数据就一直卡死等待,不释放线程JDK1.4 之前唯一 IO 模型,传统文件 IO、老式 Socket 通信都是 BIO传统网络 BIO 服务端,一个客户端连接对应一个独立线程BIO是最基础的 IO 模型,线程发起 IO 操作后会一直阻塞,直到读写完成才继续执行。
2026-05-27 21:31:23
426
原创 @Transactional 为什么会失效,别再只会回答自调用了!
在我们需要对一个方法添加事务时,我们就经常使用@Transactional 注解,表示开启事务,有异常时进行数据库操作回滚。Spring 事务用普通 ThreadLocal,子线程不会继承主线程事务上下文,连接、事务状态完全隔离。private 方法无法被子类重写,同时也无法通过代理暴露,因此事务增强无法织入。导致绕过代理,Spring AOP 是代理模式,不是字节码修改。当目标类实现接口时使用这个动态代理,生成实现目标接口的代理类。AOP 代理增强的是:对象方法,而static 无法被代理。
2026-05-16 23:53:17
328
原创 什么是内存泄漏?什么是内存溢出?
已经不再使用但是仍然被引用着导致 GC(垃圾回收)无法回收类比生活中抽象的说法:占着茅坑不拉屎,导致后面的人没地方这些无法释放的内存会不断积累。这就叫: 该释放的内存没有释放JVM 已经没有足够内存且 GC 后仍无法获得足够空间这个就是:内存溢出不该活着的(不在使用的)对象还活着,导致可用内存逐渐变小。
2026-05-14 20:39:34
242
原创 SpringBoot 项目使用 Jasypt 实现配置文件敏感信息加密
在实际项目开发中,配置文件(如)会存放数据库密码、Redis 密码、第三方接口密钥等。如果直接明文存储,一旦配置文件泄露,会带来严重的安全风险Jasypt(Java Simplified Encryption)是一款轻量级的 Java 加密工具,能完美集成 Spring Boot,,即可实现配置文件敏感信息的加密与自动解密。
2026-05-12 22:26:34
326
原创 每日一学:设计模式之策略模式
策略模式(Strategy Pattern):定义一组算法,将每个算法封装起来,并且使它们之间可以互相替换。把“变化的逻辑”抽离出来。这里统一了所有支付方式的行为。后续具体的策略实现都实现这个接口。
2026-05-11 22:42:25
386
原创 Java日志框架和使用、日志记录规范
Slf4jlog.info("日志打印");Java 日志框架的核心价值,不只是“输出内容”,而是帮助我们在开发、测试、上线、运维整个生命周期里快速理解系统发生了什么。正式项目不要依赖 System.out.println(),而要使用日志框架。推荐面向 SLF4J 编码,底层常用 Logback 或 Log4j2。合理区分 debug、info、warn、error。日志要带关键业务上下文,比如 userId、orderId、traceId。
2026-05-07 23:17:14
402
原创 PinYin4j汉字转拼音使用及踩坑
参数可选值效果大小写LOWERCASEzhongguoUPPERCASEZHONGGUO声调无声调数字声调:zhong1 guo2符号声调:zhōng guóü 处理WITH_V用 v 代替:nv标准 ü:nü。
2026-04-27 22:54:03
72
原创 每日一学:设计模式之观察者模式
观察者模式(Observer Pattern)属于,当被观察者(发布者 / 主题)状态发生变化时,所有订阅它的观察者(订阅者)会自动收到通知并执行更新逻辑。别名也叫:发布 - 订阅模式、监听者模式、Event Listener,是日常开发最常用、最易理解的设计模式之一。
2026-04-26 21:25:39
364
原创 每日一学:设计模式之适配器模式
将一个类的接口转换成客户希望的另一个接口。适配器模式让那些接口不兼容的类可以一起工作,其别名为包装器(Wrapper)。适配器模式的本质是 转换与兼容,它不是创造新功能,而是通过中间层,让原本不兼容的代码协同工作。核心作用:解决接口不兼容问题,实现解耦与复用。实现首选:对象适配器(组合),避免类适配器(继承)的单继承限制和高耦合。经典案例:JDK 的,完美诠释了适配器模式的核心逻辑。
2026-04-22 21:11:59
524
原创 每日一学:设计模式之代理模式
代理模式 = 代理人 + 真实对象,代理帮原对象处理杂事,原对象专注核心业务核心价值:不修改原代码,扩展功能(日志、权限、缓存等)两种实现:静态代理(简单)、动态代理(灵活,Spring 底层核心)
2026-04-21 09:30:00
486
原创 每日一学:设计模式之原型模式
原型模式 = 拷贝对象创建新实例Cloneableclone()浅拷贝:快,但引用类型共享深拷贝:完全独立,推荐序列化实现创建成本高、需要大量相似对象的场景。
2026-04-18 23:44:20
405
原创 每日一学:设计模式之建造者模式
建造者模式 =分离复杂对象的创建 + 组装静态内部类 Builder + 链式调用可读性高、代码优雅、对象不可变适用场景:多参数、多可选属性的复杂对象开发神器:Lombok@Builder自动生成,无需手写模板代码。
2026-04-17 09:30:00
258
原创 每日一学:设计模式之工厂模式
设计模式更多的是一种思想,一种规范,我们不应该在项目中为了使用设计模式而使用设计模式。有时候反而会适得其反,导致项目类爆炸、小模块复杂化等。过度设计只会导致维护成本增加。工厂模式是 Java 开发中二十三种设计模式 之一。属于创建型设计模式,核心思想是把对象的创建和使用分离。只需要告诉工厂需要什么对象,工厂负责创建并返回,无需关心对象是如何初始化、组装的。在实际开发中,工厂模式的思想无处不在,例如:Spring中的MyBatis中的工厂模式符合开闭原则。
2026-04-15 09:30:00
723
原创 每日一学:设计模式之单例模式
单例模式是 Java 开发中二十三种设计模式之一。属于创建者设计模式,顾名思义也就是注重对象、实例的创建。在实际开发中,单例模式广泛应用于等场景。这些场景都需要全局唯一的实例,避免重复创建对象导致的资源浪费、数据不一致等问题。例如最常用的OkHttpClient,其官方也建议使用单例模式。
2026-04-13 09:00:00
353
原创 Map集合的使用和源码
本文系统解析了Java Map集合体系,重点剖析了HashMap的实现原理。主要内容包括:1)Map基础概念与核心方法,对比HashMap、TreeMap和LinkedHashMap的特性差异;2)深度解析HashMap源码,详细讲解JDK1.8优化的底层数据结构(数组+链表+红黑树)、核心常量设计、put/get/resize等关键方法实现;3)总结TreeMap的红黑树实现和LinkedHashMap的双向链表结构;4)针对常见面试题如线程安全、负载因子选择等给出专业解答。
2026-04-09 08:30:00
703
原创 Set集合的使用和源码分析
在 Java 集合框架中,Set 是一种不允许存储重复元素、且大部分实现类不保证元素存储顺序的集合接口。它继承自Collection唯一性:不允许存储重复元素,通过元素的equals()和hashCode()方法保证;无序性:大部分实现类不记录元素的添加顺序(除外);无索引:不能通过下标访问元素,只能通过迭代器遍历。HashSet:底层基于哈希表(HashMap)实现,查询、添加、删除效率极高(O (1)),无序、非线程安全;:HashSet 的子类,底层基于哈希表 + 双向链表实现,
2026-04-06 01:52:41
384
原创 ThreadLocal的使用和源码
是 Java 并发模型中的一个关键工具类,用于实现线程隔离(Thread Confinement)为每个线程提供独立的变量副本,避免多线程之间的共享与竞争。简单理解:ThreadLocal可以实现线程之间的变量互相隔离,也就可以理解为线程的私有数据。例如:我们常用的将用户ID存储到ThreadLocal中就可以实现当前线程中可以一直使用。多数据源时将当前线程使用的数据源存在ThreadLocal中后续使用。
2026-04-02 23:21:12
366
原创 如何自己实现多数据源
本文探讨了MyBatis框架下实现多数据源动态切换的方案。通过分析MyBatis获取数据库连接的机制,发现只需在获取连接时返回不同的DataSource对象即可实现多数据源。具体实现采用AOP方式,在方法执行前切换数据源,通过重写AbstractRoutingDataSource的determineCurrentLookupKey方法,结合线程上下文ThreadLocal来动态选择数据源。配置类DataSourceConfig负责初始化多个数据源,并将CustomDataSource设为主数据源。
2026-03-30 00:00:23
529
原创 springboot实现合同生成
摘要:本文介绍了基于若依前后端分离项目的合同文档处理功能实现,主要包括用户上传含占位符({{$.}}格式)的docx模板、自动解析占位符、生成填充后的合同文档,以及格式转换流程。系统使用poi-tl和docx4j处理Word文档,通过PDFBox实现PDF转图片功能。核心功能包括:1)上传模板时解析占位符并存储;2)生成合同时替换占位符为实际内容;3)将生成的docx转为PDF,再拼接为长图。代码展示了文件路径处理、字体映射、多页PDF合并等关键实现细节,采用线程池异步处理数据库操作以提高性能。依赖包括po
2025-08-26 17:00:50
240
原创 Mybatis的Map遍历踩坑
全部都是使用entry.key来获取key,entry.value获取值。需要用到对map的遍历,获取到map的key和value值。
2025-07-04 14:25:48
412
原创 Stream的并行方法parallelStream使用和常见问题
可以将集合数据分成多个小块,分配到多个线程并行处理,从而提高程序的执行效率。而多线程是一种更加通用的并行处理方式,它可以用于任何需要同时进行多个任务的场景。简而言之:parallelStream使用多线程提高效率。
2024-12-19 17:24:25
431
原创 手写JDK动态代理实现AOP
AOP(Aspect Oriented Programming,面向切面编程)在 Java 中的实现有多种方式,其中使用 JDK 动态代理和 CGLIB 代理较为常见。当你的应用程序遵循面向接口编程的原则时,JDK 动态代理是一个自然的选择。如果你的目标对象实现了一个或多个接口,并且你希望在不修改目标对象代码的情况下为其添加额外的功能,如日志记录、性能监测、安全检查等,那么可以使用 JDK 动态代理。对象如果实现了接口就是用jdk动态代理,否则使用cglib。
2024-11-11 00:39:21
589
原创 数据库错误[ERR] 1071 - Specified key was too long; max key length is 1000 bytes
把default-storage-engine=MyISAM改为default-storage-engine=INNODB即可。因为默认使用MyISAM,MyLSAM限制1000 bytes,超出报错,将Mysql改为Innodb即可。试了还是有问题,直接启动不了了。因为mysql8取消了这个配置。环境:phpstudy的mysql8。
2024-06-11 12:44:55
1331
1
原创 Gateway报错Consider defining a bean of type ‘org.springframework.http.codec.ServerCodecConfigurer‘
2024-06-06 16:28:22.116 ERROR [service-gateway,,,] 22452 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter : ***************************APPLICATION FAILED TO START***************************Description:Parameter 0 of method modifyRespo
2024-06-06 16:33:51
613
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅