同学们,帮我表弟检查下代码?
背景
表弟刚参加工作半年,就遇到批量调用接口返回错误的问题,刚好是周五遇到让周六加班弄完,由于周六本是休息,表弟积极性很低,于是直接选择短平快的方式先应付上去,并且运行了一下,说日志有空指针报错,但核对了一下数据库数据正常,暂时没发现问题。
为了保险起见让我帮忙给review一下
表弟说用大模型分析,老是回答说存在问题,让换一种写法,但大模型的那些问题像是在专业的胡说,不太放心自己临时写的代码。说经常看很多人喜欢review代码,就跑过来让我看一下,我看完后心中已有数。但为了表弟面前表现的更专业,故将其代码去除所有业务信息,做了最简化处理让各位也来点评一下,博采众长。
顺便吆喝一句,技术大厂跳板,前后端/测试,多地捞人机会,待遇还可以~感兴趣的冲冲!
表弟的代码(极简版)
表弟的环境是jdk8的单体服务,此接口调用频率很低,但一旦调用并发量很多。
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.locks.ReentrantLock;
@Slf4j
@RequestMapping("/queue")
@RestController
public class QueueController {
//服务一旦宕机,队列消息就会全部丢失
private static final Queue<String> queue = new LinkedBlockingQueue<>(10000);
private static final ReentrantLock lock = new ReentrantLock();
/**
* 通过内存占用换取接口的并发能力,请求进来先进队列里排队,最后一个走的线程检查一下队列是否处理完成
* @param id 模拟任务对象
*/
@RequestMapping("/offer")
public void test(@RequestParam("id")String id){
if(id != null) {
//模拟生产任务
boolean offered = queue.offer(id);
if(!offered){
log.error("消息进入队列失败:{}",id);
}
}
boolean isLock = lock.tryLock();
if(isLock) {
try {
while (!queue.isEmpty()) {
String poll = queue.poll();
try {
if (poll != null) {
log.info("poll:{}", poll);
//模拟消费任务耗时,此处可以异步再优化性能
Thread.sleep(1000);
}
}catch (Exception e){
log.error("消费任务出错,poll:{},错误信息{}",poll,e.getMessage(),e);
}
}
} catch (Exception e) {
log.error("消费任务出现异常,id:{},错误信息:{}",id,e.getMessage(),e);
} finally {
if(lock.isHeldByCurrentThread()){
lock.unlock();
//进入判断前可以加个10ms的睡眠时间,进一步降低高并发下总是此线程拿到锁的可能,从而不断递归导致栈溢出
if(!queue.isEmpty()){
log.info("清理队列剩余任务,size:{}",queue.size());
test(null);
}
}
}
}
log.info("生产者执行完成,size:{}",queue.size());
}
}
——转载自:我的咖啡要加糖
#牛客创作赏金赛#

