java多线程简单处理高并发问题

java多线程处理高并发问题

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;
    }
}

局限性

由于化同步为异步,每次请求接口的返回值时唯一的,因此该方法只适用于请求方不需要返回时的场景。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值