type
status
date
slug
summary
tags
category
icon
password
背景
在一次开发里,我需要加载一批测试数据到内存,但是不希望花太多时间和空间在加载的过程上,于是需要做一个超时限制。这可以通过创建一个
CompletableFuture
来实现,并且通过 get(long timeout, TimeUnit unit)
方法限制等待时间。但是我忽略了一个问题,
get(long timeout, TimeUnit unit)
超时以后,并不会让原来的线程停止,这样内存中的数据还是会不断增长,导致出现一些预期外的状况。那么,怎么去取消之前运行的线程呢?
验证
首先,创建一个例子说明
get(long timeout, TimeUnit unit)
超时并不影响线程继续执行。可以看到,线程已经执行执行超时了,但是还是会继续保持运行。
解决方案
自然而然的,我们想到了这个类提供的
cancel(boolean mayInterruptIfRunning)
方法,在超时异常处理里对这个线程调用 cancel
处理就好了吧,类似于下面这部分代码。但实际上,这并没有实现预期效果。
这是因为线程一旦获取到 CPU 资源,在执行过程中就无法取消了。
因此,解决方案是在执行代码中添加逻辑判断,跳过业务处理的执行。如下面的代码所示,添加了一个 final 修饰的变量
running
,通过判断这个变量让程序空跑,跳过实际处理。当然,这样会有 CPU 的资源浪费。