繁体   English   中英

如何以线程安全的方式为新用户分配递增的用户ID?

[英]How do I assign an incrementing user ID to new users in a thread-safe manner?

我刚刚开始学习Java,我在创建Java服务器时遇到了问题。

在HTML上,应该有一个表单,JavaScript会每秒提交一次表单(通过POST方法)。 表单应该有一个隐藏字段,其中包含用户ID的值。 服务器应在请求中查找用户标识。 它应该为新用户提供新ID,并向访问过的用户显示他们的ID。

每个表单提交后,题字更改为:null,2,null,2,null,2 ....这里是代码:

public class ServerConnect extends AbstractHandler{
         private AtomicInteger ids = new AtomicInteger(0);    
         private String userId;

         public void handle(String target,
         Request baseRequest,
         HttpServletRequest request,
         HttpServletResponse response)    throws IOException, ServletException
         {

             response.setContentType("text/html;charset=utf-8");
             response.setStatus(HttpServletResponse.SC_OK);
             baseRequest.setHandled(true);
             response.getWriter().println(PageGenerator.generateForm(userId));
             userId = request.getParameter("userId");

             if (userId == null){
                 ids.getAndIncrement();
                 userId = ids.toString();
             }        
          }

         public static void main(String[] args) throws Exception {

               Server server = new Server(8080);
               server.setHandler(new ServerConnect());
               server.start();
               server.join();
        }
}

public class PageGenerator {

    public static String generateForm(String val){
        String htmlCode = null;

        htmlCode = "...
             <script>
                function reload(){ 
                   document.forms['MainForm'].submit();
                }
                setTimeout("reload()", 1000); 
             </script>    
             .... + val + ...
             <form id='MainForm' method = 'POST'>
                 <input type = "hidden" name = "userId" value = \""+ val + \""> 
             <form>
                             ...       
    return htmlCode;
    }    

}

我无法理解为什么用户ID等于2,以及为什么在用户获得他的id之后,它的值变为null,然后再次变为2

您似乎在解析userId之前渲染了您的页面。 在检查if(userId == null)之前,您有PageGenerator.generateForm(userId) if(userId == null)

此外,您应该了解AtomicLong.getAndIncrement()是一个复合操作,类似于i++ (但是是单个原子操作)。

所以你需要有如下代码:

if (userId == null){
     userId = ids.getAndIncrement();
} 

最后,我不确定AbstractHandler的生命周期,但假设您的类的新实例每隔一个请求由Jetty实例化是合理的。 由于ids的范围是“实例”字段,因此它会被新请求丢弃(从而有效地重置)。

在Jetty的线程模型上编辑答案: Jetty Architecture

要解决这个问题,你需要将ids声明为static final (从而有效地使它成为“Singleton”ID生成器)以使其在多个请求中存活。 玩具应用程序的好方法,但不是生产代码中必须做的事情。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM