主要是为了解决Redis的缓存问题,异步将用户信息存入Redis缓存
首先我们需要引入一部线性池
核心概念
-
异步执行:
- 异步执行是指任务提交后不会立即等待其完成,而是立即返回并继续执行其他任务。任务将在后台执行,执行结果可以通过回调、Future、Promise 等机制获取。
- 异步执行通常意味着任务不会阻塞当前线程,也就是当前线程可以继续做其他事情。
-
线程池:
- 线程池是一个维护一组线程的集合,任务提交给线程池后,线程池会从线程池中取出一个空闲线程来执行任务,而不是每次都新建一个线程。线程池能够有效地管理线程的生命周期,避免线程创建和销毁的开销。
-
任务提交与执行:
- 异步线程池中的任务是被异步地执行的。任务可以通过提交接口(例如
submit()
或execute()
)被提交到线程池中,线程池的线程会异步执行这些任务。提交的任务一般是 Callable 或 Runnable 类型。
- 异步线程池中的任务是被异步地执行的。任务可以通过提交接口(例如
-
异步结果:
- 异步任务执行完毕后,通常会返回一个结果。Java 中可以通过
Future
对象获取结果或状态。通过Future.get()
方法可以获取任务执行的结果(注意get()
是阻塞方法),如果你只关心任务是否完成,可以使用isDone()
方法。
- 异步任务执行完毕后,通常会返回一个结果。Java 中可以通过
java
@Configuration
public class ThreadPoolConfig {
@Bean(name = "taskExecutor")
public Executor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10);
executor.setMaxPoolSize(50);
executor.setQueueCapacity(200);
executor.setKeepAliveSeconds(30);
executor.setThreadNamePrefix("UserExecutor-");
// 拒绝策略:由调用线程处理(一般为主线程)
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
// 等待所有任务结束后再关闭线程池
executor.setWaitForTasksToCompleteOnShutdown(true);
// 设置等待时间
executor.setAwaitTerminationSeconds(60);
executor.initialize();
return executor;
}
}
下面展示用户信息存入 Redis 缓存的部分代码
java
// 根据用户 ID 查询用户信息
UserDO userDO = userDOMapper.selectById(userId);
// 判空
if (Objects.isNull(userDO)) {
threadPoolTaskExecutor.execute(() -> {
// 防止缓存穿透,将空数据存入 Redis 缓存 (过期时间不宜设置过长)
long expirationTime = 60 + RandomUtil.randomInt(60);
redisTemplate.opsForValue().set("这里自己定义key值", "null", expirationTime, TimeUnit.SECONDS);
});
throw new (根据自己设置的异常);
}