JUC线程池ThreadPoolExecutor源码分析

前提

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

public interface Executor {

void execute(Runnable command);
}

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

阅读更多
JUC线程池扩展可回调的Future

前提

最近在看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]版本上运行,其他版本可能不适合。

阅读更多
深入理解Instrument(一)

前提

很早之前就了解到目前主流的APM开源框架如PinpointSkyWalking等等都是通过java.lang.instrument包提供的字节码增强功能来实现的。趁着对这块的热情还没消退,抽时间分析一下java.lang.instrument包的使用方式,记录下来写成一个系列的文章。本系列博文针对的是JDK11,其他版本的JDK可能不适合。

阅读更多
Java线程生命周期与状态切换

Java线程生命周期与状态切换

前提

最近有点懒散,没什么比较有深度的产出。刚好想重新研读一下JUC线程池的源码实现,在此之前先深入了解一下Java中的线程实现,包括线程的生命周期、状态切换以及线程的上下文切换等等。编写本文的时候,使用的JDK版本是11。

阅读更多
深入理解Java中的Garbage Collection

前提

最近由于系统业务量比较大,从生产的GC日志(结合Pinpoint)来看,需要对部分系统进行GC调优。但是鉴于以往不是专门做这一块,但是一直都有零散的积累,这里做一个相对全面的总结。本文只针对HotSpot VM也就是Oracle Hotspot VM或者OpenJDK Hotspot VM,版本为Java8,其他VM不一定适用。

什么是GC(Garbage Collection)

Garbage Collection可以翻译为“垃圾收集” – 一般主观上会认为做法是:找到垃圾,然后把垃圾扔掉。在VM中,GC的实现过程恰恰相反,GC的目的是为了追踪所有正在使用的对象,并且将剩余的对象标记为垃圾,随后标记为垃圾的对象会被清除,回收这些垃圾对象占据的内存,从而实现内存的自动管理。

阅读更多
Hystrix完整配置列表

前提

Hystrix在2018年11月20日之后已经停止维护,最后一个提交记录是:Latest commit 3cb2158 on 20 Nov 2018,最后一个正式版本为1.5.18。鉴于目前所在公司的技术栈是Spring Cloud,熔断和降级组件主要用的还是Hystrix,这里就Hystrix的完整列表做一个分析记录,方便以后可以随时查询。本文主要参考:Hystrix Configuration。其中,命令配置是针对HystrixCommand,主要包括命令执行(execution)配置、命令降级(fallback)配置、熔断器(circuit breaker)配置、度量统计(metrics)配置和请求上下文配置。

阅读更多
内部分享-Spring Cloud Gateway初体验Slides

内部分享-聊聊常用的线程模型Slides

Spring Cloud Gateway-使用自定义过滤器通过Hystrix实现降级处理

前提

在微服务架构中,下游依赖出现问题如果上游调用方不做请求降级处理,下游的异常依赖没有被隔离,很有可能出现因为一两个服务或者小到一两个接口异常导致上游所有服务不可用,甚至影响整个业务线。请求降级处理目前比较主流的依然是Netfilx出品的HystrixHystrix的工作原理是:

  • 把请求基于线程池或者信号量隔离,一旦下游服务在指定配置的超时时间内无法响应会进入预设或者默认的降级实现。
  • 每个请求的状态都会记录下来,在一个滑动窗口内处理失败的比率超过设定的阈值就会触发熔断器(Circle Breaker)开启,熔断器开启之后所有请求都会直接进入预设或者默认的降级逻辑。
  • 熔断器打开后,且距离熔断器打开的时间或上一次试探请求放行的时间超过设定值,熔断器器进入半开状态,允许放行一个试探请求。
  • 请求成功率提高后,基于统计数据确定对熔断器进行关闭,所有请求正常放行。

这里不对Hystrix的细节做更深入分析,而是接着谈谈Spring Cloud Gateway中如何使用Hystrix,主要包括内置的Hystrix过滤器和定制过滤器结合Hystrix实现我们想要的功能。除了要引入spring-cloud-starter-gateway依赖之外,还需要引入spring-cloud-starter-netflix-hystrix

<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
</dependencies>
阅读更多
经典面试题-两个线程交替打印奇数和偶数

前提

今天下班时候和同事聊天偶然听到面试题“两个线程交替打印奇数和偶数”的实现,这里做一个复盘。

阅读更多