自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

七夜

java成长之路

  • 博客(28)
  • 收藏
  • 关注

原创 ThreadLocal系列之——父子线程传递线程私有数据(四)

前情回顾前文,介绍了ThreadLocal作者们(Josh Bloch and Doug Lea)为内存泄露做的努力,将内存泄露造成的影响降到了最低,且着重分享了软件设计上的一个Trade Off:如何权衡内存占用与CPU占用之间的关系,该折中思想与Redis的过期淘汰策略一致(知识的迁移)本文,将会接着分享ThreadLocal的其他局限性,并给出相应的解决方案局限性局限性一:父线程无法通过ThreadLocal向子线程传递线程私有数据首先,通过本系列第二篇文章的学习,我们可以肯定的是:Thre

2020-09-13 10:29:39 885 8

原创 ThreadLocal系列之——JDK为内存泄露做的努力(三)

前情回顾前文,介绍ThreadLocal不恰当使用姿势造成的内存泄露问题,提醒大家使用完ThreadLocal须记得调用remove方法及时回收,避免内存泄露诚然,不恰当的使用姿势确实有内存泄露的问题,但JDK作者们为了降低内存泄露对应用程序造成的影响绞尽脑汁,想尽了办法,做了各种各样的努力和尝试,本文就来看看作者们做了什么额外的补救措施这是任何一款成熟的商业产品该具有的模样:核心业务代码占比应是少部分,而围绕在核心代码之外的大部分代码都是为了产品体验更友好,考虑的更周全,能应付各种恶劣的场景)

2020-09-05 19:38:17 401 5

原创 ThreadLocal系列之——内存泄露剖析(二)

回顾前文,介绍了ThreadLocal的使用姿势,并分享业务实战场景,其中提到了一个重要的点:每次请求结束后需要清理ThreadLocal,避免内存泄露前文由于篇幅原因并未铺张开来细聊,故此本文将围绕ThreadLocal内存泄露这个点进行详细的剖析,旨在锻炼表达能力,同时分享给各位正文本文所有源码基于JDK 1.8.0_192,不同版本之间实现方式或细节或有出入,请以手中的源码为准ThreadLocal数据结构要理解ThreadLocal内存泄露的原因,首先需要了解TheadLocal其数

2020-08-30 21:10:40 378 2

原创 ThreadLocal系列之——业务开发实践(一)

写作目的以前的工作经历中,笔者本人有深度使用ThreadLocal的经验,它在合适的场景下,是非常好用的一个工具,因此打算分享一二,为各位看官们实际编码过程中提供多一种选择,促进大家共同进步场景先举两个大家熟悉的、Spring中用到的场景场景一在Spring管理的Singleton Bean中,如果期望调用同一个类里被事务注解的方法(m1调用m2),且希望事务能生效,可以考虑的实现如下:@Servicepublic class FooService { public void m1(

2020-08-23 21:40:52 374 4

原创 Spring Shutdown Hook工作机制揭秘

前言上篇文章,我们讨论了在Spring环境中正确关闭线程池的姿势,抛出了问题并给出了解决方案。本篇,将接着讨论解决方案背后的原理:Spring Shutdown Hook工作机制源码解析源码基于Spring Boot 2.1.0.RELEASE注册Spring Shutdown Hook的时机首先要找到入口在哪,即Spring Shutdown Hook是在哪注册的,很容易猜想,应该是在应用启动过程中注册的,找到如下源码位置:org.springframework.boot.SpringApp

2020-07-23 21:53:09 9655 3

原创 Spring环境中正确关闭线程池的姿势

前言在Java System#exit 无法退出程序的问题探索一文末尾提到优雅停机的一种实现方案,要借助Shutdown Hook进行实现,本文,将继续探索优雅停机中遇到的一些问题:应用中线程池的优雅关闭线程池正确关闭的姿势在这一节,先不讨论应用中线程池该如何优雅关闭以达到优雅停机的效果,只是简单介绍一下线程池正确关闭的姿势为简化讨论的复杂性,本文的线程池均是指JDK中的java.util.concurrent.ThreadPoolExecutor正确关闭线程池的关键是 shutdown +

2020-07-19 10:58:32 14014 16

原创 Java System#exit 无法退出程序的问题探索

背景有朋友碰到了一个情况:java.lang.System#exit无法退出应用程序。我听到这种情况的时候是感觉很惊奇的,这函数还能不起作用?这就好奇不已了呀接着,朋友继续给出了他的场景描述:在Dubbo应用连接注册中心的时候,如果连接(超时)失败,期望调用System#exit退出应用程序,但是程序并没有按期望退出,JVM进程还存在与此同时,如果把执行System#exit的代码放到另一个线程,程序可以按期望退出,JVM进程结束用伪代码描述如下:Future<Object> futu

2020-06-07 00:56:13 5660 1

原创 Spring构造器注入循环依赖的解决方案及原理探索

前言我们都知道Spring解决了Setter注入或者Field注入的循环依赖问题,依靠的是三个Map(earlySingletonObjects、singletonFactories、singletonObjects),网上有许多资料分析了原理,此文就不再赘述。但是,构造器注入下的循环依赖,Spring并没有直接解决,因此网上有许多文章都会说Spring的构造器注入循环依赖无解,实则不然,Spr...

2020-03-29 16:49:30 8885 14

原创 Java如何让线程池满后再放队列

背景最近收到一道面试题:我们知道JDK的线程池在线程数达到corePoolSize之后,先判断队列,再判断maximumPoolSize。如果想反过来,即先判断maximumPoolSize再判断队列,怎么办?建议往下浏览之前先思考一下解决方案,如果自己面对这道面试题,该如何作答?方案一由于线程池的行为是定义在JDK相关代码中,我们想改变其默认行为,很自然的一种想法便是:继承自JDK的线...

2020-03-14 14:42:00 5995 6

原创 JDK Proxy与UndeclaredThrowableException不可不说的关系

背景最近浏览Sentinel的wiki,其中有一段描述:特别地,若 blockHandler 和 fallback 都进行了配置,则被限流降级而抛出 BlockException 时只会进入 blockHandler 处理逻辑。若未配置 blockHandler、fallback 和 defaultFallback,则被限流降级时会将 BlockException 直接抛出(若方法本身未定义...

2020-02-22 14:16:36 724

原创 PreparedStatement重新认知(2)——防止SQL注入

回顾上篇,我们对PreparedStatement在MySQL下的工作机制进行了探究,了解到它在一般情况下并不比Statement更快(具体分析可参看: PreparedStatement重新认知(1)——它真的预编译吗),但我们还是建议使用它的原因是,它有一个非常重要的特性是Statement所不具备的:防止SQL注入正文引用wikipedia对SQL注入的定义:SQL inject...

2020-02-16 22:31:04 505 5

原创 PreparedStatement重新认知(1)——它真的预编译吗

起因最近在阅读数据库连接池相关的书籍,书中有一小节提到了Statement与PreparedStatement的区别,并指出使用PreparedStatement会对SQL进行预编译,并将预编译的SQL存储下来,下次直接使用,提高效率。与之相对的是Statement,它需要频繁进行编译,从这个角度而言,PreparedStatement会比Statement更快,但事实真的是这样的吗?书中并没有...

2020-02-06 10:31:23 1685

原创 AutowireCapableBeanFactory探密(3)——依赖解析

前情回顾在前两篇文章中,多次提及AutowireCapableBeanFactory#resolveDependency方法,原因是该方法很重要,在Spring很多场合都涉及该方法的调用,包括但不限于以下场景:解析@Resouce注解的元素(CommonAnnotationBeanPostProcessor#autowireResource)解析@Autowired、@Value注解的元素...

2020-02-02 01:15:30 719

原创 AutowireCapableBeanFactory探密(2)——传统装配模式与现代注解驱动注入方式

回顾上篇,介绍了AutowireCapableBeanFactory的作用:让Spring管理的Bean去装配和填充那些不被Spring托管的Bean,为第三方框架赋能。其中,介绍AutowireCapableBeanFactory接口时简单提了一下该接口定义了6个属性,其中有5个(AUTOWIRE_*)是与autowireMode相关的常量值定义,用于描述该用何种方式来进行装配Bean正文...

2020-01-14 14:15:03 1249

原创 AutowireCapableBeanFactory探密(1)——为第三方框架赋能

起因群里有朋友抛出了个问题,问为什么Spring Cache注解未生效,示例代码如下:@RunWith(SpringRunner.class)@SpringBootTest@Slf4jpublic class DemoApplicationTests { @Test public void contextLoads() { testGetFromDB(1)...

2020-01-07 17:01:48 1240

原创 磁盘满了对日志打印(Logback)的影响

使用Logback日志框架,当磁盘满了后不必惊慌,它不会对应用程序产生太负面影响。仔细考虑,做为一个日志框架本该如此,不能因为写不了日志就抛出异常进而影响应用本身,毕竟,日志终究是个辅助的旁路逻辑,没有它应用也应该work well。底层知识的掌握有助于迅速理解上层应用。在阅读源码的过程中,我发现了非常熟悉的设计逻辑:即类似于Hystrix的断路器和RocketMQ消费失败重试的策略。由于之前有相关经验,因此我很快就能够理解作者的设计意图。

2023-10-09 21:08:33 897

原创 编码高可用的一点思考

背景最近,公司里许多项目因为各种原因(如工期问题、个人习惯问题、经验问题),导致出现了一些线上性能问题,进而影响了服务可用性。在此分享一些个人编码中高可用的思考习惯正文先来提问一个问题,如果在程序中跑如下SQL(base on MySQL),有问题吗?select * from t_order where id = #{orderId};hang住,别往下看,思考30s答案是:或许有,或许没有只给了一条SQL,其它上下文都缺失,无法判断是否会有问题。一些可能出问题的点:projetio

2022-03-03 21:52:01 577

原创 Spring Boot加载application.properties探究

背景基于Spring Boot的多Module项目中,有许多公共的配置项,为避免在每个接入层都配置一遍,一个设想是在公共依赖的Module的application.properties(application.yml)中进行配置。原来的配置文件位于接入层的classpath,可由Spring Boot打包插件打入,一旦置于公共Module,配置文件就不再直接被打入jar包,而是位于内嵌的jar包...

2019-12-16 13:34:12 908

原创 Mybatis优雅存取json字段的解决方案 - TypeHandler (二)

回顾上篇,我们分析了TypeHandler的注册过程,分析了12个register方法之间盘根错节的关系,最终得出注册过程就是构建三个Map的过程。在这个过程中,为使文章脉络清晰,跳过了@MappedTypes、@MappedJdbcTypes注解相关的内容。跳过并非不重要,相反,这俩注解在自定义TypeHandler的过程中扮演着相当重要的角色,因此,为使知识点完整,本文将分析@MappedT...

2019-12-10 14:40:07 5012 2

原创 Mybatis优雅存取json字段的解决方案 - TypeHandler (一)

起因在业务开发过程中,会经常碰到一些不需要检索,仅仅只是查询后使用的字段,例如配置信息,管理后台操作日志明细等,我们会将这些信息以json的方式存储在RDBMS表里假设某表foo的结构如下,字段bar就是以json的方式进行存储的idbarcreate_time1{“name”:“Shary”,“quz”:10,“timestamp”:1574698533370}2...

2019-11-30 23:37:23 21932 9

原创 Spring Boot + Apollo 动态修改日志级别

起因你是否碰到过如下场景:在测试环境未发现的BUG,上了生产环境之后偶现,但同样由于缺少调试信息,无法定位问题调用内部服务、第三方服务,在某些case下系统未按预期运行,排查代码后怀疑是被依赖方返回了错误的数据导致,但苦于打印Response的日志为DEBUG,没有证据在以前的解决方案是,将日志级别改成DEBUG并上个线,排查完问题之后,再将日志级别改回INFO,再上一次线,整个生命周...

2019-11-24 22:46:46 3711

原创 JDK1.8 Supplier实践及总结

起因群里黑神抛出了一个问题,意图引起大家的思考黑神简单解释之后,群里仍有同学不太理解正好之前笔者在Supplier上有一些实践,因此打算跟大家分享一下使用经验基础知识JDK1.8为我们提供了一个函数接口Supplier,先来看一下它的接口定义@FunctionalInterfacepublic interface Supplier<T> { /** ...

2019-11-09 15:18:26 2076 8

原创 Spring MVC统一异常处理及原理分析(二)

前言上篇,我们已经阐述在Spring MVC中如何优雅地处理异常,并通过源码分析了其原理及工作过程。但是一定会有同学产生疑问:原来的异常处理方式,可以直接在catch块中打印请求入参,当异常发生时,能够清晰知道是什么入参导致的异常,方便问题的排查。使用统一异常处理的方案,只打印了异常堆栈,丢失了相关上下文信息,怎么办?try { // do biz} catch (Exception e...

2019-10-25 14:05:46 537

原创 Spring MVC统一异常处理及原理分析

文章会从三个方面进行分析:提出统一异常处理机制的好处,以及该机制使用姿势提供案例:不使用该机制会产生什么样的情况机制背后对应的原理分析(重点)机制好处及使用姿势Spring MVC为我们的WEB应用提供了统一异常处理机制,其好处是:业务逻辑和异常处理解耦(业务代码不应该过多地关注异常的处理[职责单一原则])消除充斥各处的try catch块代码,使代码更整洁便于统一向前端、客...

2019-09-21 11:01:36 1601

原创 Spring MVC参数解析之ParameterNameDiscoverer

大家知道,Spring MVC 有一项非常实用的功能,叫参数绑定。其具体能实现的功能异常强大,这里不再赘述,网上有非常多的资料可供参考,仅举一例用以描述问题。@RestControllerpublic class FooController { @GetMapping(&quot;/methodOne&quot;) public Boolean methodOne(Integer fil...

2018-12-11 23:42:45 5408 3

原创 MySQL之rewriteBatchedStatements

网上很多文章,都说MySQL驱动并没有实现”真正的”batchUpdate,执行的时候还是一条一条按顺序将SQL发送到MySQL服务器,其实这是错误的。先贴一段源码(基于MySQL 5.1.40驱动),执行batchUpdate的时候最终执行如下方法:executeBatchInternalprotected long[] executeBatchInternal() throws S...

2018-03-14 23:53:50 6859 10

原创 MySQL死锁case分析

死锁发现2018-01-18 14:10:03 线上环境批量更新库存的地方出现了死锁2018-01-25 16:50:03 线上环境批量更新库存的地方出现了死锁org.springframework.dao.DeadlockLoserDataAccessException: PreparedStatementCallback; SQL [UPDATE goods_inventor

2018-02-07 22:02:17 2816

转载 Java字节码指令

Java字节码指令 Java 字节码指令及javap 使用说明### java字节码指令列表 字节码 助记符 指令含义 0x00 nop 什么都不做 0x01 aconst_null 将null推送至栈顶 0x02 iconst_m1 将int型-1推送至栈顶 0x03 iconst_0 将int型0推送至栈顶 0x04 i

2017-10-21 23:02:45 414

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除