前提

今天(2020-01-18)在编写Netty相关代码的时候,从Netty源码中的ThreadDeathWatcherGlobalEventExecutor追溯到两个和线程上下文类加载器ContextClassLoader内存泄漏相关的Issue

两个Issue分别是两位前辈在2017-12的时候提出的,描述的是同一类问题,最后被Netty的负责人采纳,并且修复了对应的问题从而关闭了Issue。这里基于这两个Issue描述的内容,对ContextClassLoader内存泄漏隐患做一次复盘。

前提

之前的一篇文章JUC线程池ThreadPoolExecutor源码分析深入分析了JUC线程池的源码实现,特别对Executor#execute()接口的实现做了行级别的源码分析。这篇文章主要分析一下线程池扩展服务ExecutorService接口的实现源码,同时会重点分析Future的底层实现。ThreadPoolExecutor和其抽象父类AbstractExecutorService的源码从JDK8到JDK11基本没有变化,本文编写的时候使用的是JDK11,由于ExecutorService接口的定义在JDK[8,11]都没有变化,本文的分析适用于这个JDK版本范围的任意版本。最近尝试找Hexo可以渲染Asciidoc的插件,但是没有找到,于是就先移植了Asciidoc中的五种Tip

前提

很早之前就打算看一次JUC线程池ThreadPoolExecutor的源码实现,由于近段时间比较忙,一直没有时间整理出源码分析的文章。之前在分析扩展线程池实现可回调的Future时候曾经提到并发大师Doug Lea在设计线程池ThreadPoolExecutor的提交任务的顶层接口Executor只有一个无状态的执行方法:

1
2
3
4
public interface Executor {

void execute(Runnable command);
}

ExecutorService提供了很多扩展方法底层基本上是基于Executor#execute()方法进行扩展。本文着重分析ThreadPoolExecutor#execute()的实现,笔者会从实现原理、源码实现等角度结合简化例子进行详细的分析。ThreadPoolExecutor的源码从JDK8到JDK11基本没有变化,本文编写的时候使用的是JDK11。

前提

最近在看JUC线程池java.util.concurrent.ThreadPoolExecutor的源码实现,其中了解到java.util.concurrent.Future的实现原理。从目前java.util.concurrent.Future的实现来看,虽然实现了异步提交任务,但是任务结果的获取过程需要主动调用Future#get()或者Future#get(long timeout, TimeUnit unit),而前者是阻塞的,后者在异步任务执行时间不确定的情况下有可能需要进行轮询,这两种情况和异步调用的初衷有点相违背。于是笔者想结合目前了解到的Future实现原理的前提下扩展出支持(监听)回调的Future,思路上参考了Guava增强的ListenableFuture。本文编写的时候使用的JDK是JDK11,代码可以在JDK[8,12]版本上运行,其他版本可能不适合。

前提

Doug Lea大神在编写JUC(java.util.concurrent)包的时候引入了java.util.concurrent.locks.AbstractQueuedSynchronizer,Abstract Queued Synchronizer,也就是”基于队列实现的抽象同步器”,一般我们称之为AQS。其实Doug Lea大神编写AQS是有严谨的理论基础的,他的个人博客上有一篇论文《The java.util.concurrent Synchronizer Framework》,文章在http://ifeve.com上可以找到相关的译文(《JUC同步器框架》),如果想要深入研究AQS必须要理解一下该论文的内容,然后详细分析一下AQS的源码实现。本文在阅读AQS源码的时候选用的JDK版本是JDK11。

AQS的主要功能

AQS是JUC包中用于构建锁或者其他同步组件(信号量、事件等)的基础框架类。AQS从它的实现上看主要提供了下面的功能:

  • 同步状态的原子性管理。
  • 线程的阻塞和解除阻塞。
  • 提供阻塞线程的存储队列。

基于这三大功能,衍生出下面的附加功能:

  • 通过中断实现的任务取消,基于线程中断实现。
  • 可选的超时设置,也就是调用者可以选择放弃等待。
  • 定义了Condition接口,用于支持管程形式的await/signal/signalAll操作,代替了Object类基于JNI提供的wait/notify/notifyAll。

AQS还根据同步状态的不同管理方式区分为两种不同的实现:独占状态的同步器共享状态的同步器

前提

最近接触到的一个项目要兼容新老系统,最终采用了ThreadLocal(实际上用的是InheritableThreadLocal)用于在子线程获取父线程中共享的变量。问题是解决了,但是后来发现对ThreadLocal的理解不够深入,于是顺便把它的源码阅读理解了一遍。在谈到ThreadLocal之前先买个关子,先谈谈黄金分割数。本文在阅读ThreadLocal源码的时候是使用JDK8(1.8.0_181)。