how-do-servlets-work-initialization-shared-variables-and-multithreading
2015-11-19 14:06
381 查看
http://stackoverflow.com/questions/3106452/how-do-servlets-work-instantiation-shared-variables-and-multithreading/3106909#3106909
question:
Suppose, I have a webserver which holds numerous
Now, if 2 or more users send request to this server then what happens to the session variables? Will they all be common for all the users or they will be different for each user. If they are different, then how was the server able to differentiate between
different users?
One more similar question, if there are
answer:
Apache Tomcat) starts up, it will deploy and load all webapplications. When a webapplication get loaded, the servletcontainer will create the
When the
new
The request object provides access to all information of the HTTP request, such as the request headers and the request body. The response object provides facility to control and send the HTTP response the way you want, such as setting headers and the body
(usually with HTML content from a JSP file). When the HTTP response is committed and finished, then both the request and response objects will be trashed.
As per the HTTP cookie specification (a contract a decent webbrowser and webserver has to adhere), the client (the webbrowser) is required to send this cookie back in the subsequent requests
in the
Net/Network tab). The servletcontainer will determine the
The
request, even though with the cookie specified, will not have access to the same session anymore. The servletcontainer will create a new one.
On the other hand, the session cookie on the client side has a default lifetime which is as long as the browser instance is running. So when the client closes the browser instance (all tabs/windows), then the session will be trashed at the client side. In
a new browser instance the cookie associated with the session won't be sent anymore. A new
all requests in all sessions.
The
all requests in the same session.
The
not being shared elsewhere.
Any
all requests in all sessions.
Any
of the same instance. It would otherwise have been too expensive to recreate it on every request.
But you should also realize that you should never assign any request or session scoped data as an
instance variable of a servlet or filter. It will be shared among all other requests in other sessions. That's
threadunsafe! The below example illustrates that:
http://stackoverflow.com/questions/3106452/how-do-servlets-work-instantiation-shared-variables-and-multithreading/3106909#3106909
question:
Suppose, I have a webserver which holds numerous
Servlets. For information passing among those
ServletsI am getting the
Servletscontext and setting session variables.
Now, if 2 or more users send request to this server then what happens to the session variables? Will they all be common for all the users or they will be different for each user. If they are different, then how was the server able to differentiate between
different users?
One more similar question, if there are
*n*users accessing a particular
Servlets, then this
Servletsgets instantiated only the first time the first user accessed it or does it get instantiated for all the users separately?
answer:
ServletContext
When the servletcontainer (likeApache Tomcat) starts up, it will deploy and load all webapplications. When a webapplication get loaded, the servletcontainer will create the
ServletContextonce and keep in server's memory. The webapp's
web.xmlwill be parsed and every
<servlet>,
<filter>and
<listener>found in
web.xml, or annotated with respectively
@WebServlet,
@WebFilterand
@WebListener, will be created once and kept in server's memory as well. For all filters, the
init()method will also be invoked immediately. When the servletcontainer shuts down, it will unload all webapplications, invoke the
destroy()of all initialized servlets and filters, and finally the
ServletContextand all
Servlet,
Filterand
Listenerinstances will be trashed.
When the
Servletin question has a
<servlet><load-on-startup>or
@WebServlet(loadOnStartup)value greater than
0, then its
init()method will also immediately be invoked during startup. Those servlets are initialized in the same order as "load-on-startup" value represents, or if they are the same, then the order in the
web.xmlor
@WebServletclassloading. Or, if the "load-on-startup" value is absent, then the
init()method will only be invoked on very first HTTP request hitting the servlet in question.
HttpServletRequest and HttpServletResponse
The servletcontainer is attached to a webserver which listens on HTTP requests on a certain port number, which is usually 8080 in development and 80 in production. When a client (user with a webbrowser) sends a HTTP request, the servletcontainer will createnew
HttpServletRequestand
HttpServletResponseobjects and pass it through the methods of the already-created
Filterand
Servletinstances whose
url-patternmatches the request URL, all in the same thread.
The request object provides access to all information of the HTTP request, such as the request headers and the request body. The response object provides facility to control and send the HTTP response the way you want, such as setting headers and the body
(usually with HTML content from a JSP file). When the HTTP response is committed and finished, then both the request and response objects will be trashed.
HttpSession
When a client visits the webapp for the first time and/or theHttpSessionis to be obtained for the first time by
request.getSession(), then the servletcontainer will create it, generate a long and unique ID (which you can get by
session.getId()) and store it in server's memory. The servletcontainer will also set a
Cookiein the
Set-Cookieheader of the HTTP response with
JSESSIONIDas cookie name and the unique session ID as cookie value.
As per the HTTP cookie specification (a contract a decent webbrowser and webserver has to adhere), the client (the webbrowser) is required to send this cookie back in the subsequent requests
in the
Cookieheader as long as the cookie is valid. Using browser builtin HTTP traffic monitor you can check them (press F12 in Chrome / Firefox23+ / IE9+ and check
Net/Network tab). The servletcontainer will determine the
Cookieheader of every incoming HTTP request for the presence of the cookie with the name
JSESSIONIDand use its value (the session ID) to get the associated
HttpSessionfrom server's memory.
The
HttpSessionlives until it has not been used for more than the
<session-timeout>time, a setting you can specify in
web.xml, which defaults to 30 minutes. So when the client doesn't visit the webapp anymore for over 30 minutes, then the servletcontainer will trash the session. Every subsequent
request, even though with the cookie specified, will not have access to the same session anymore. The servletcontainer will create a new one.
On the other hand, the session cookie on the client side has a default lifetime which is as long as the browser instance is running. So when the client closes the browser instance (all tabs/windows), then the session will be trashed at the client side. In
a new browser instance the cookie associated with the session won't be sent anymore. A new
request.getSession()would return a brand new
HttpSessionand set a cookie with a brand new session ID.
In a nutshell
TheServletContextlives as long as the webapp lives. It's been shared among
all requests in all sessions.
The
HttpSessionlives as long as the client is interacting with the webapp with the same browser instance and the session hasn't timed out at the server side yet. It's been shared among
all requests in the same session.
The
HttpServletRequestand
HttpServletResponselives as long as the client has sent it until the complete response (the webpage) is arrived. It is
not being shared elsewhere.
Any
Servlet,
Filterand
Listenerlives as long as the webapp lives. They are being shared among
all requests in all sessions.
Any
attributewhich you set in
ServletContext,
HttpServletRequestand
HttpSessionwill live as long as the object in question lives.
Threadsafety
That said, your major concern is possibly threadsafety. You should now have learnt that Servlets and filters are shared among all requests. That's the nice thing of Java, it's multithreaded and different threads (read: HTTP requests) can make useof the same instance. It would otherwise have been too expensive to recreate it on every request.
But you should also realize that you should never assign any request or session scoped data as an
instance variable of a servlet or filter. It will be shared among all other requests in other sessions. That's
threadunsafe! The below example illustrates that:
public class ExampleServlet extends HttpServlet { private Object thisIsNOTThreadSafe; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Object thisIsThreadSafe; thisIsNOTThreadSafe = request.getParameter("foo"); // BAD!! Shared among all requests! thisIsThreadSafe = request.getParameter("foo"); // OK, this is thread safe. } }
相关文章推荐
- 解决 Selenium文件上传框无法识别的问题
- reStructuredText(.rst)语法规则快速入门
- 变态的静态资源缓存与更新
- 对微信的二次打包学习2:安装多个微信
- [BZOJ2748][HAOI2012]音量调节
- Java三大特性(封装 继承 多态)
- Ubuntu android开发环境问题
- Linux或Windows下安装Laravel5.0
- 使用AsyncTask的常见问题及解决方式
- python开源项目目录结构参考
- 几个lamda表达式
- 35个java代码性能优化总结
- [leetcode 276] Paint Fence
- 五角形图片
- 常用的Web服务器
- win7下oracle11g监听和数据库服务都无法启动
- 如何分享一个文件
- 设置修改Tomcat的UTF-8编码
- iOS开发实践:一个类微博客户端从启动到与用户交互的过程
- HDU 5532 / 2015ACM/ICPC亚洲区长春站 F.Almost Sorted Array