Hi All,
I am wondering why calling javax.servlet.Servlet#getServletConfig() is
thread safe: if you check the implementation in
javax.servlet.GenericServlet from servlet API 3.0.1, you see the following:
package javax.servlet;
// lines omitted
public abstract class GenericServlet
implements Servlet, ServletConfig, java.io.Serializable
{
// lines omitted
private transient ServletConfig config;
// lines omitted
public void init(ServletConfig config) throws ServletException {
this.config = config;
this.init();
}
// lines omitted
public ServletConfig getServletConfig() {
return config;
}
// lines omitted
}
The field config is written in init(ServletConfig) without any
synchronization, locking or config being volatile, while getServletConfig()
could be called anytime from any later worker thread of the servlet
container. I took a quick look into Tomcat/Catalina code base, however I
see no indication of the servlet container performing any magic, which
would guarantee thread safe access to field config through
getServletConfig() from e.g.
javax.servlet.GenericServlet#service(ServletRequest, ServletResponse) and
the corresponding methods in javax.servlet.http.HttpServlet.
Am I missing something here? What will guarantee that if Thread A is used
to init(ServletConfig) then Thread B calling getServletConfig() will see
the correct state of the field config (Java "happens-before"), and not e.g.
null?
I am asking this because I have seen some legacy code, where a servlet
stored something into a field inside the init() method, which was then used
from within a javax.servlet.http.HttpServlet#doGet or
javax.servlet.http.HttpServlet#doPost method, without synchronization of
any kind like this:
public class FoobarServlet extends HttpServlet {
private FoobarService foobarService;
@Override
public void init() throws ServletException {
this.foobarService = // ... acquire foobarService
}
protected void doGet(HttpServletRequest request, HttpServletResponse
response) throws ServletException, IOException {
List<Foobar> foobars = this.foobarService.getFoobars(); // read the
field WITHOUT synchronization
// ...
}
// ...
Is this approach (having no synchronization, locking or the field being
volatile) correct? I assumed it is not, seeing something like that in the
servlet API is quite confusing.
What do you think?
Thanks,
Peter