技术分享:Java多线程学习处理高并发问题
在程序的应用程序中,用户或请求的数量达到一定数量,并且无法避免并发请求.由于对接口的每次调用都必须在返回时终止,因此,如果接口的业务相对复杂,则可能会有多个用户。调用接口时,该用户将冻结。
以下内容将介绍解决此问题的巧妙且非常简单的方法.
请求写入内存
我们可以将每个请求封装为一个对象,然后将其写入内存.
@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多线程学习处理高并发问题的内容,希望对大家有所帮助。
本文来自千锋教育,转载请注明出处。
更多相关文章
- 什么是整型类型?Python整型详细介绍
- 前端开发零基础好学吗?
- 技术分享:Python如何进行内存管理?
- Ulysses 22 发布功能加强,允许自定义分组颜色
- 软测经典面试题(二)
- 如何避免ajax重复请求?
- HTML、HTML5重难点
- 基于机器阅读理解(MRC)的信息抽取方法
- 深度学习技术在美图个性化推荐的应用实践