在程序的应用程序中,用户或请求的数量达到一定数量,并且无法避免并发请求.由于对接口的每次调用都必须在返回时终止,因此,如果接口的业务相对复杂,则可能会有多个用户。调用接口时,该用户将冻结。

以下内容将介绍解决此问题的巧妙且非常简单的方法.

请求写入内存

我们可以将每个请求封装为一个对象,然后将其写入内存.

@Getter
@Setter
private static class CallVo{//请求对象
private Long param1;//参数1
private Integer param2;//参数2
}
private List<CallVo> callVoList = new ArrayList<>();//请求对象列表
/**
* 接口调用
* @param callVo
* @return
*/
@Transactional
@RequestMapping(value = "/call",method = {RequestMethod.POST})
public void call(@RequestBody CallVo callVo){
synchronized (syncObject) {
callVoList.add(callVo);//将请求对象写入内存
}
}
多线程处理

创建一个线程以继续读取内存中的数据. 如果被请求对象的收集长度为0多线程技术问题解决,则表明没有请求. 如果集合中有数据,请从集合中删除请求的对象并获取时间. 根据相应业务处理请求的参数.

这达到了将同步转变为异步的目的,并简单地解决了高并发性的问题.

private Thread thread;
private final Object syncObject = new Object(); // 同步对象
private volatile boolean runnable;
@Override
public void run() {
while (runnable){
try {
if (callVoList.size() == 0) {//集合长度为0,证明没有请求
Thread.sleep(1000);
continue;
}
CallVo callVo;
synchronized (syncObject) {
callVo = callVoList.remove(0);
}
Long param1 = callVo.getStationId();
Integer param2 = callVo.getCallType();

//业务处理
System.out.println(param1+"---"+param2);

}catch (Exception e){
logger.error("接口调用异常:", e);
}
}
}

完整代码:

@RestController
@Slf4j
@RequestMapping("/erpRemote")
public class ErpRemoteController extends BaseController implements DisposableBean, Runnable{

ErpRemoteController(){
callVoList = new ArrayList<>();
runnable = true;
thread = new Thread(this);
thread.start();
}
/**
* 接口调用
* @param callVo
* @return
*/
@Transactional
@RequestMapping(value = "/call",method = {RequestMethod.POST})
public GeneralResponse call(@RequestBody CallVo callVo){

synchronized (syncObject) {
callVoList.add(callVo);//将请求对象写入内存
}
return GeneralResponse.success(null);
}
@Getter
@Setter
private static class CallVo{//请求对象
private Long param1;//参数1
private Integer param2;//参数2
}
private List<CallVo> callVoList;
private Thread thread;
private final Object syncObject = new Object(); // 同步对象
private volatile boolean runnable;
@Override
public void run() {
while (runnable){
try {
if (callVoList.size() == 0) {//集合长度为0,证明没有请求
Thread.sleep(1000);
continue;
}
CallVo callVo;
synchronized (syncObject) {
callVo = callVoList.remove(0);
}
Long param1 = callVo.getStationId();
Integer param2 = callVo.getCallType();

//业务处理
System.out.println(param1+"---"+param2);

}catch (Exception e){
logger.error("接口调用异常:", e);
}
}
}
@Override
public void destroy() {
runnable = false;
}
}
限制

由于同步是异步的,因此每次请求接口的返回值都是唯一的多线程技术问题解决,因此此方法仅适用于请求者不需要返回的情况.

以上就是小千介绍的Java多线程学习处理高并发问题的内容,希望对大家有所帮助。

本文来自千锋教育,转载请注明出处。


©著作权归作者所有:来自51CTO博客作者戏精程序媛的原创作品,如需转载,请注明出处,否则将追究法律责任

更多相关文章

  1. 什么是整型类型?Python整型详细介绍
  2. 前端开发零基础好学吗?
  3. 技术分享:Python如何进行内存管理?
  4. Ulysses 22 发布功能加强,允许自定义分组颜色
  5. 软测经典面试题(二)
  6. 如何避免ajax重复请求?
  7. HTML、HTML5重难点
  8. 基于机器阅读理解(MRC)的信息抽取方法
  9. 深度学习技术在美图个性化推荐的应用实践

随机推荐

  1. Android 背景色平铺。
  2. android 环境的搭建
  3. wifi和GPRS下获取android的IP信息
  4. android之写文件到sd卡
  5. 安卓布局
  6. Android 的Platform version 和 API Leve
  7. Android xml ListView 的divider属性
  8. [Android各版本特性]Android 7.0 Nougat
  9. Android自学笔记(番外篇):全面搭建Linux环境
  10. android布局属性预览