java - 如何以线程安全的方式将递增的用户 ID 分配给新用户?

标签 java servlets

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

在 HTML 上,应该有一个表单,JavaScript 每秒都会提交该表单(通过 POST 方法)。该表单应该有一个隐藏字段,其值为用户 ID。服务器应在请求中查找用户 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)

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

所以你需要有如下代码:

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

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

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

要解决此问题,您需要将 ids 声明为 static final(从而有效地使其成为“单例”ID 生成器)以使其在多个请求中存活。对于玩具应用程序来说是一种不错的方法,但不是您在生产代码中必须做的事情。

关于java - 如何以线程安全的方式将递增的用户 ID 分配给新用户?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12586758/

相关文章:

java - httpservletrequest - 创建新 session /更改 session ID

html - 如何使用 Servlet 从 HTML 表单中检索 URDU 数据(UTF-8)以插入 MYSQL 数据库

java - 更改 Min Sdk 版本后 "Cannot resolve symbol ' R '"?

java - 不使用break停止for循环

java - 上传中保存文件的路径我真的应该选择 getServletContext 吗?

java - 将应用程序与 VC++ 应用程序集成

java - 使用 currentTimeMillis 并关闭 6 小时

javascript - 获取引用页面Servlet的URL

java - Java 中的 RequestDispatcher

java - 通过servlet进入登录页面后,如何将用户名值放入欢迎页面?