【问题标题】:java multiple servlets thread safety of hashtable哈希表的java多servlet线程安全
【发布时间】:2014-12-28 11:58:29
【问题描述】:

在我的应用程序中,我有一个执行登录和其他操作的 servlet。 在这个单一的 servlet 中,我将用户存储在一个以会话 ID 为键的 hastable 中。

Hashtable<string,MySession> sessions; //sessionid and MySession instance

但是登录过程有点复杂并且包含业务问题,所以我决定分开,我想要两个servlet,一个用于登录,一个用于操作 .登录 servlet 将生成 MySession 并将其存储并将客户端转发给 operation servlet。因此,两个 servlet loginoperation 必须共享这个哈希表。

问题是,

  • 我当前的结构是线程安全的吗?我的意思是这个单一的 servlet 实例,我将所有用户存储在一个 hastable 中?我有诸如 addNewSession 和 clearSession 之类的哈希表修改方法。 (我使用浏览器会话 ID 作为键)。我没有使这些方法同步,因为不建议使用这种方法(servlet 的单个实例)

  • 如果我声明这个 hastable static 会发生什么,这样我就可以从两个新分离的 servlet(登录和操作)访问它

  • 如果我将此 hastable 存储在父 servlet 中并从该 servlet 扩展登录和操作,以便两者都可以访问其父 servlet 保护的哈希表实例,该怎么办?

  • 使用 servlet 上下文方法,我从上下文到达另一个 servlet 还是直接将哈希表存储在上下文中?它会解决线程安全问题吗?或者我认为我应该 为 getServletContext() 返回的 ServletContext 对象提供同步,因为它在 myapplication 中的 servlet 之间共享?

目前的结构是:

public SingleServlet extends HttpServlet {
     Hashtable<string,MySession> sessions = new Hashtable();

     public void doGet(HttpRequest request, HttpResponsr response) {
         String sessionId = request.getSessionId();

         if (sessions.get(sessionId) == null) {
             // Create a new session and store
             // Do login operations
             MySession iNewSession = new MySession(..);

             // Thread safety??
             sessions.put(sessionId, iNewSession);
         } else {
             // Already existing session, operate on that
             MySession iExistingSession = sessions.get(sessionId);

             // Check if operation is logout
             if (isLogout(request)) {
                iExistingSession.performLogout();

                // Thread safety??
                sessions.remove(sessionId);
             } else
             iExistingSession.continueOperation(request, response);
         }

【问题讨论】:

  • 为什么要重新发明原生会话已经在做的事情?
  • 你的意思是apache shiro?
  • 不,我是说 HttpSession。这正是它的本质:每个会话 ID 的哈希表,您可以在其中存储您想要的任何属性。

标签: java servlets thread-safety hashtable shared


【解决方案1】:

您的代码不是线程安全的。虽然单个操作(如 putgetremove)是原子的和线程安全的,但一系列操作(例如 get 后跟 put)不是线程安全的。

【讨论】:

  • 我相信 java.util.concurrent 下的 ConcurrentHashMap 从 1.5 开始是比 Hashtable 更好的选择,但是在这种情况下它会解决问题吗?或者您有什么其他建议?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-11-14
  • 2014-05-05
  • 2011-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-24
相关资源
最近更新 更多