一篇教会你java使用线程池异步实战
接口调用时间缩短
文章目录
前言
提示:实战可用:
在当今高度并发的软件开发领域,有效地处理大量请求并提高系统的性能是至关重要的。Java提供了强大的线程池机制,使得异步编程成为提高应用程序效率的有力工具。本文将带领您深入了解Java线程池,并通过实际示例展示如何在项目中应用异步编程的最佳实践。
随着用户对实时性和响应速度的不断追求,传统的同步编程模型可能显得力不从心。线程池作为一种优秀的解决方案,不仅能够更有效地管理资源,还能够实现任务的并行执行,从而显著提高系统的并发处理能力。
在接下来的文章中,我们将深入探讨以下主题:
为什么使用线程池?
Java线程池的基本概念和工作原理。
如何通过线程池实现异步编程,提高系统的响应速度。
实际项目中的线程池应用场景与最佳实践。
无论您是初学者还是有一定经验的开发者,通过本文,您将获得在Java中使用线程池进行异步编程的实际技能,为您的项目提供更出色的性能和用户体验。
让我们一起探索Java线程池的奥秘,为您的应用程序注入新的活力!
提示:以下是本篇文章正文内容,下面案例可供参考
一、我们来开始吧?
我数据库里面有都少数据先看一下:
才一百多条 我这里会多个表进行查询 增加 修改
二、使用步骤
1.项目中的 resources
我们先新建一个
这个里面的内容呢 :
com.cn.blogboot.autoconfiguration.ThreadPoolAutoConfiguration
输入上面这个是我自己新建的一个class
代码如下(示例):
package com.cn.blogboot.autoconfiguration;
import com.cn.blogboot.properties.ThreadPoolExecutorProperties;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
@Configuration
@EnableConfigurationProperties(ThreadPoolExecutorProperties.class)
@ConditionalOnProperty(prefix = "thread.pool", name = "enable", havingValue = "true")
public class ThreadPoolAutoConfiguration {
@Bean
public ThreadPoolExecutor threadPoolExecutor(ThreadPoolExecutorProperties properties) {
return new ThreadPoolExecutor(properties.getCorePoolSize(),
properties.getMaximumPoolSize(),
properties.getKeepAliveTime(),
TimeUnit.SECONDS,
new LinkedBlockingQueue<>(10000),
Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());
}
}
然后新建一个实体
package com.cn.blogboot.properties;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
@Getter
@Setter
@ConfigurationProperties(prefix = "thread.pool")
public class ThreadPoolExecutorProperties {
/** 核心池大小 */
private final Integer corePoolSize = 20;
/** 最大池大小 */
private final Integer maximumPoolSize = 200;
/** 维持时间 */
private final Long keepAliveTime = 15L;
}
然后yaml 里面进行配置 咋个配置呢
thread:
pool:
enable: true
开启就可以了
2.怎么使用
来咯来咯:看我操作我的一个案例
代码如下(示例):
package com.cn.blogboot.service.exchange.impl;
import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cn.blogboot.constants.UserConstants;
import com.cn.blogboot.dto.ExchangeDot;
import com.cn.blogboot.exception.CustomException;
import com.cn.blogboot.mapper.ExchangeMapper;
import com.cn.blogboot.mapper.UserInfoMapper;
import com.cn.blogboot.model.UserModel;
import com.cn.blogboot.pojo.Exchange;
import com.cn.blogboot.pojo.UserInfo;
import com.cn.blogboot.service.IUserInfoService;
import com.cn.blogboot.service.exchange.IExchangeService;
import com.cn.blogboot.util.MinioClientConfig;
import com.cn.blogboot.util.RedisUtils;
import com.cn.blogboot.util.SimpleDateFormatUtils;
import com.cn.blogboot.vo.ExchangeVo;
import com.cn.blogboot.vo.HeadPortrait;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
@Service
@Transactional(rollbackFor = Exception.class)
@RequiredArgsConstructor
@Slf4j
public class ExchangeServiceImpl extends ServiceImpl<ExchangeMapper, Exchange> implements IExchangeService {
private final ExchangeMapper exchangeMapper;
private final UserInfoMapper userInfoMapper;
private final MinioClientConfig minioClientConfig;
/** 线程 */ // 这个一定要导入
private final ThreadPoolExecutor thread;
private final RedisUtils redisUtils;
@Override
public void useRedemptionCode(ExchangeDot dot) {
Object object = redisUtils.hashGet(UserConstants.USER_INFO, StpUtil.getLoginId().toString());
UserModel userModel = (UserModel) object;
ExchangeVo vo = new ExchangeVo();
//查询兑换码是否过期 & 已经使用
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
Optional<Exchange> exchange = Optional.ofNullable(exchangeMapper.selectOne(new LambdaUpdateWrapper<Exchange>()
.eq(Exchange::getRedemptionCode, dot.getRedemptionCode()).eq(Exchange::getStatus, 0)));
exchange.ifPresentOrElse((e)->{
final Date effectiveDate = e.getEffectiveDate();
System.out.println("时间"+effectiveDate);
if(SimpleDateFormatUtils.isExpired(effectiveDate)){
throw new CustomException("兑换码已过期",500);
}
vo.setExchange(e);
}, () -> {
throw new CustomException("兑换码不存在",500);
});
System.out.println("数据包"+vo);
}, thread);
// 修改 future.thenCompose((unused) -> CompletableFuture.runAsync(() -> { 等待上一个线程完成
CompletableFuture<Void> useRedemptionCode = future.thenCompose((unused) -> CompletableFuture.runAsync(() -> {
final UserInfo userInfo = userInfoMapper.selectOne(new LambdaQueryWrapper<UserInfo>().eq(UserInfo::getOpenId,userModel.getOpenId()));
Exchange exchange = vo.getExchange();
if(exchange!=null){
Long treasuryCurrency = exchange.getTreasuryCurrency();
System.out.println("库币"+treasuryCurrency);
userInfoMapper.update(new UserInfo().setAiCoin(userInfo.getAiCoin()+treasuryCurrency),new LambdaUpdateWrapper<UserInfo>()
.eq(UserInfo::getOpenId,userModel.getOpenId()));
}
}, thread));
//修改兑换码状态
CompletableFuture<Void> updateRedemptionCode = CompletableFuture.runAsync(() -> {
exchangeMapper.update(new Exchange().setStatus(1L),new LambdaUpdateWrapper<Exchange>()
.eq(Exchange::getRedemptionCode,dot.getRedemptionCode()));
}, thread);
try {
//堵塞任务执行
CompletableFuture<Void> allOf = CompletableFuture.allOf(future, useRedemptionCode, updateRedemptionCode);
allOf.get(5, TimeUnit.SECONDS);
} catch (Exception e) {
// 下面这个是我自己的返回业务
String customExceptionMessage="";
String exceptionString = e.getMessage();
String[] parts = exceptionString.split("[=,)]");
if (parts.length >= 4) {
String message = parts[1].trim();
int code = Integer.parseInt(parts[3].trim());
CustomException customException = new CustomException(message, code);
customExceptionMessage = customException.getMessage();
}
throw new CustomException(customExceptionMessage,500);
}
}
}
我上面是查询兑换码 然后修改然后 在进行使用 返回速度
CompletableFuture 是 Java 8 引入的一个类,用于支持异步编程和并发操作。它提供了一种方便的方式来处理异步任务的结果,以及对多个异步任务的组合和组织。CompletableFuture 类实现了 Future 接口
可以增加删除查询修改 异步执行 提高接口的速度 ,我这里写了一个案例
更多复杂业务 可以自行对照写
直接拉满~~~~
总结
这个可是很实用的,自测 调用超级快,更多优化实用的东西等你来