zoukankan      html  css  js  c++  java
  • 大批量推送项目日记(三):正确防止接口被短时间内多次调用的方法

    2020.8.5

    今天,本人发现了一个问题:

    本人编写的代码提供了一个接口(url),当接口被调用时,会先从数据库中查找status不为1的记录(也就是未推送与推送失败的记录),获取每行的userID,然后把userID当做参数发送一个http请求,发送完毕后根据返回信息修改status,记为1(推送成功)或2(推送失败),以此实现了给用户推送信息。

    正常情况下,调用一次本人的接口后,status会被修改,成功的改为1,失败的改为2;不影响下次调用。

    但是,如果有人在短时间内多次调用本人的接口,会造成多个线程从数据库中查到相同的数据(此时status还没有来得及被修改),然后多个线程发送相同的http请求,就会造成一个用户收到多个相同的推送信息。

    为了解决这个问题,本人想到了一个方法,代码如下(自测没有问题):

    //记录当前线程的变量,不允许多个线程同时运行
    public static Thread nowThread = null;
    
    ......
    
    //线程主方法
    public void pushTask(){
    
      //如果有正在执行的线程,新线程就不继续执行
    
      if(nowThread != null && nowThread.isAlive()){
        LOG.info("当前存在正在执行的线程,本次线程不执行,请稍后再试");
        return;
      }
    
      else{
        nowThread = Thread.currentThread();
      }
      
      //主要代码省略
      ......
    
      //线程执行完毕,置空
      nowThread = null;
    
    }

    1.上方的代码增加了一个static类型的Thread对象,保存上一次执行过的线程对象

    2.当一个新的线程执行到该方法时,进行判断,如果上一次执行的线程不为null且存活,则自己不再执行,直接return

    3.否则,新线程把自己的对象保存到nowThread

    4.线程执行完成时,将nowThread置为null(这个好像不写也可以)

    5.即使线程执行到一半意外停止,也不会影响新线程的执行,新线程根据isAlive()方法可以判断出来上一个线程是否存活。

    -----------------------------------------------------------------------------------------------------------------------------

    这个方法目前自测没有发现问题,也许不是最好的解决方法,但是应该能解决问题了。

    如果大家有更好的解决方法,欢迎在评论区留言,谢谢!

  • 相关阅读:
    <<< List<HashMap<String, Object>> 及 HashMap<String, Object> 的用法
    <<< html图片背景平铺
    <<< javascript地址栏,代码
    Linux下常用目录有哪些?分别有什么作用?
    【Linux】Linux下进程间的通信方式
    【Linux】守护进程的定义,作用,创建流程
    【Linux】进程的结构,创建,结束,以及程序转化为的进程的过程
    【Linux】僵尸进程,孤儿进程以及wait函数,waitpid函数(有样例,分析很详细)
    【Linux】多线程同步的四种方式
    【Linux】多线程入门详解
  • 原文地址:https://www.cnblogs.com/codeToSuccess/p/13906221.html
Copyright © 2011-2022 走看看