笔者之前在查找Sentinel相关资料的时候,偶然中找到了Martin Fowler
大神的一篇文章《CircuitBreaker》。于是花了点时间仔细阅读,顺便温习一下断路器CircuitBreaker
的原理与实现。
笔者做小数据和零号提数工具人已经有一段时间,服务的对象是运营和商务的大佬,一般要求导出的数据是Excel
文件,考虑到初创团队机器资源十分有限的前提下,选用了阿里出品的Excel
工具EasyExcel
。这里简单分享一下EasyExcel
的使用心得。EasyExcel
从其依赖树来看是对apache-poi
的封装,笔者从开始接触Excel
处理就选用了EasyExcel
,避免了广泛流传的apache-poi
导致的内存泄漏问题。
之前已经花了大量时间分析同步器框架AQS
的源码实现,这篇文章分析一下CountDownLatch
的源码实现,本文参看的JDK
源码为JDK11
,其他版本不一定适合。
CountDownLatch其实是复合名词,由单词countdown和latch复合而来。countdown是倒数的意思,而latch则是闩锁、闭锁的意思,复合词容易让人联想到预先设定一个计数值,并且"锁住(阻塞)“一些东西(线程),然后进行倒数,当数值减少到0的时候进行"放行(解除阻塞)”。
CountDownLatch
是AQS共享模式下的典型实现。本文会先简单介绍CountDownLatch
的基本API
、类比监视器方式的实现以及深入分析其源码实现。
很早之前就打算看一次JUC线程池ThreadPoolExecutor
的源码实现,由于近段时间比较忙,一直没有时间整理出源码分析的文章。之前在分析扩展线程池实现可回调的Future
时候曾经提到并发大师Doug Lea
在设计线程池ThreadPoolExecutor
的提交任务的顶层接口Executor
只有一个无状态的执行方法:
public interface Executor {
void execute(Runnable command);
}
而ExecutorService
提供了很多扩展方法底层基本上是基于Executor#execute()
方法进行扩展。本文着重分析ThreadPoolExecutor#execute()
的实现,笔者会从实现原理、源码实现等角度结合简化例子进行详细的分析。ThreadPoolExecutor
的源码从JDK8
到JDK11
基本没有变化,本文编写的时候使用的是JDK11
。
并发编程大师Doug Lea在编写JUC
(java.util.concurrent
)包的时候引入了java.util.concurrent.locks.AbstractQueuedSynchronizer
,其实是Abstract Queued Synchronizer
,也就是"基于队列实现的抽象同步器",一般我们称之为AQS
。其实Doug Lea
大神编写AQS
是有严谨的理论基础的,他的个人博客上有一篇论文《The java.util.concurrent Synchronizer Framewor》,可以在互联网找到相应的译文《JUC同步器框架》,如果想要深入研究AQS
必须要理解一下该论文的内容,然后结合论文内容详细分析一下AQS
的源码实现。本文在阅读AQS
源码的时候选用的JDK
版本是JDK11
。
出于写作习惯,下文会把AbstractQueuedSynchronizer称为AQS、JUC同步器框或者同步器框架。
最近有一个数据统计服务需要升级SpringBoot
的版本,由1.5.x.RELEASE
直接升级到2.3.0.RELEASE
,考虑到没有用到SpringBoot
的内建SPI
,升级过程算是顺利。但是出于代码洁癖和版本洁癖,看到项目中依赖的MyBatis
的版本是3.4.5
,相比当时的最新版本3.5.5
大有落后,于是顺便把它升级到3.5.5
。升级完毕之后,执行所有现存的集成测试,发现有部分OffsetDateTime
类型入参的查询方法出现异常,于是进行源码层面的DEBUG
找到最终的问题并且解决。
最近有点懒散,没什么比较有深度的产出。刚好想重新研读一下JUC
线程池的源码实现,在此之前先深入了解一下Java
中的线程实现,包括线程的生命周期、状态切换以及线程的上下文切换等等。编写本文的时候,使用的JDK
版本是11。
笔者很久之前就有个想法:参考现有的主流ORM
框架的设计,造一个ORM
轮子,在基本不改变使用体验的前提下把框架依赖的大量的反射设计去掉,这些反射API
构筑的组件使用动态编译加载的实例去替代,从而可以得到接近于直接使用原生JDBC
的性能。于是带着这样的想法,深入学习Java
的动态编译。编写本文的时候使用的是JDK11
。
最近一两个月花了很大的功夫做UCloud
服务和中间件迁移到阿里云的工作,没什么空闲时间撸文。想起很早之前写过ThreadLocal
的源码分析相关文章,里面提到了ThreadLocal
存在一个不能向预先创建的线程中进行变量传递的局限性,刚好有一位HSBC
的技术大牛前同事提到了团队引入了transmittable-thread-local解决了此问题。借着这个契机,顺便clone
了transmittable-thread-local
源码进行分析,这篇文章会把ThreadLocal
和InheritableThreadLocal
的局限性分析完毕,并且从一些基本原理以及设计模式的运用分析transmittable-thread-local
(下文简称为TTL
)整套框架的实现。
如果对线程池和ThreadLocal
不熟悉的话,可以先参看一下前置文章:
这篇文章前后花了两周时间编写,行文比价干硬,文字比较多(接近5W
字),希望带着耐心阅读。
用Java
快三年了,注解算是一个常用的类型,特别是在一些框架里面会大量使用注解做组件标识、配置或者策略。但是一直没有深入去探究JDK
中的注解到底是什么,底层是怎么实现了?于是参考了一些资料,做了一次稍微详细的分析。
1 / 6