在我的应用程序中,我有一个执行登录和其他操作的servlet。 在这个单独的servlet中,我将用户存储在由会话ID键入的hastable中。
Hashtable<string,MySession> sessions; //sessionid and MySession instance
但是登录过程有点复杂并且包含业务问题,所以我决定分开,我希望有两个servlet用于登录,一个用于操作 。登录servlet将生成MySession并将其存储并将客户端转发到操作 servlet。因此,两个servlet 登录和操作必须共享此哈希表。
问题是,
是我当前的结构threadafed?我的意思是这个单一的servlet实例,我将所有用户存储在hastable中?我有哈希表修改方法,如addNewSession和clearSession。 (我使用浏览器会话ID作为密钥)。我没有使这个方法同步,因为没有建议这种方法(servlet的单个实例)
如果我声明这个hastable static会发生什么,所以我可以从两个新的分离的servlet(登录和操作)到达它
如果我将这个hastable存储在父servlet中并从该servlet扩展登录和操作,以便两者都可以到达其父servlet受保护的哈希表实例,该怎么办?
使用servlet contenxt方法,我从上下文到达另一个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);
}
答案 0 :(得分:0)
您的代码不是线程安全的。虽然单个操作(如put
,get
和remove
)是原子和线程安全的,但是一系列操作(例如get
后跟put
)不是线程安全的。