【发布时间】:2014-12-28 11:58:29
【问题描述】:
在我的应用程序中,我有一个执行登录和其他操作的 servlet。 在这个单一的 servlet 中,我将用户存储在一个以会话 ID 为键的 hastable 中。
Hashtable<string,MySession> sessions; //sessionid and MySession instance
但是登录过程有点复杂并且包含业务问题,所以我决定分开,我想要两个servlet,一个用于登录,一个用于操作 .登录 servlet 将生成 MySession 并将其存储并将客户端转发给 operation servlet。因此,两个 servlet login 和 operation 必须共享这个哈希表。
问题是,
我当前的结构是线程安全的吗?我的意思是这个单一的 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