In Java, How do I make sure my web application is thread safe?
How do I make sure my java servlets web application is thread safe? What do I need to do in regards to session variables, static variables of a class, or 开发者_如何学运维anything else that could be a thread-safety problem?
Fact: there's only 1 instance of a servlet in webapp's lifetime. It get created on webapp's startup and it get destroyed on webapp's shutdown. Also see this answer for a rough interpretation.
Thus, it's been shared among all requests (threads). If you assign request or session scoped data as instance (or even worse, as static
) variable, then it is definitely not threadsafe, because it's then been shared among all requests (threads) from all users (sessions) applicationwide. You just need to assign them as method local variables to keep them threadsafe. So:
public class MyServlet 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.
}
}
That's basically all you need to take into account when developing servlets with threadsafety in mind.
Then there are session (HttpSession
) attributes which can be shared among multiple requests from the same user, but in real world you actually don't need to worry about synchronizing session access. You normally put only user-specific data there, such as the logged-in user, user-specific preferences, the shopping basket, etcetera. You just need to ensure that you don't put pure request scoped data in the session scope. It would get reflected in multiple browser windows/tabs inside the same session.
Then there are application (ServletContext
) attributes which are shared among all users applicationwide, but you normally put only constants and other static data there, like the webapp configuration, DAO factory, dropdownlist contents, etcetera. This all can by the way be done with a ServletContextListener
, also see this answer for a basic example. You just need to ensure that you don't put pure request- or session scoped data in the application scope.
- don't use instance variables of servlets and filters
- don't use static variables
- read this article on session thread safety
- think
Wow, that's a loaded question.
To put it simply, you need to ensure that access to any shared data is carefully synchronized. E.g., you may want to synchronize access to a static variable with a mutex or a synchronized function.
Note that you may also need to synchronize at higher levels if you need atomic transactions that modify multiple shared resources at the same time.
Designing a concurrent application is not simple, and there is no magic bullet (unfortunately). I highly recommend the book "Java Concurrency in Practice" for more information on writing safe concurrent code.
Do you mean in a context as opposed to any other java application? There really isn't much difference. Each request to a servlet causes the container to issue a new thread to handle it, so instance variables within the servlet must be thread-safe. It's better to handle all your biz with local variables in the doGet / doPost() methods. There is one gotcha that I can think of. With session variables, it may be the case that the user has two browser windows open, both pointing to your application. In this case you would need to watch out for thread safety with the session scope as well.
精彩评论