[concurrency-interest] Safety of initializations in Servlet init
matthias at mernst.org
Mon Aug 2 09:41:19 EDT 2010
On Sat, Jul 31, 2010 at 7:19 AM, Karl Krukow <kkr at trifork.com> wrote:
> On 30/07/2010, at 20.15, Kris Schneider wrote:
>> On Fri, Jul 30, 2010 at 1:05 PM, Karl Krukow <kkr at trifork.com> wrote:
>> The article you reference below is almost 10 years old and common (or
>> at least better) practice has moved on to use ServletContextListener.
> Even so, the question is still valid: why is it safe to do an initialization of an instance variable in one thread (in the init method) and read the variable in another thread (in the service method) without synchronization. There must be two scenarios: (i) either it's isn't really safe and the common pattern is really broken; or (ii) app servers perform some form of synchronization under the hood to ensure a happens-before relation between the write in the init and the read in the service method.
> Hopefully it is not (i), but the problem with (ii) is that as far as I can see, it isn't mentioned in the servlet or portlet specifications so if coding strictly to the spec the programmer would have to synchronize.
> Regarding: ServletContextListener: I didn't know that using it is common best practice, and the servlet spec still writes about the init method (servlet 2.5, SRV.2.3.2):
> >>After the servlet object is instantiated, the container must initialize the servlet before it can handle requests from clients. Initialization is provided so that a servlet can read persistent configuration data, initialize costly resources (such as JDBCTM API- based connections), and perform other one-time activities. The container initializes the servlet instance by calling the init method of the Servlet interface with a unique (per servlet declaration) object implementing the ServletConfig interface.<<
I think the keywords are "must...before". I'd argue that this prose
naturally translates to "happens before" in JMM lingo. The only
reasonable ways to implement this requirement introduce happens-before
relationships: for example the "worker pool threads" are only started
after the init methods have run or the container worker safely
communicates an initialization bit to the workers or a new,
initialized servlet instance is safely published into some
Then "Write to servlet instance variables" happens-before "init-method
finishes" happens-before "request is dispatched to servlet"
happens-before "read from instance variable".
If a container instead performed an unsafe busy wait loop on the
servlet instance, there are probably more things to run away
screamingly from such container...
That said, back in the 4.x times, a chief Tomcat maintainer resisted
to necessary synchronization related to session timeout and on-demand
JSP compilation if I remember correctly. But those simply were bugs
IMHO that undermined my trust in the implementation and not the spec.
> In either case, in the servlet context listener, the same question applies, but Brian's article you mention below shows that it is up to the user to synchronize if storing an object in the servlet context.
>> Although I don't recall that Servlet.init is specifically covered,
>> this is a more recent and much more informative article on state and
>> concurrency in the context of servlet containers:
> Yes, thanks for that (good) reference. I remember reading that some time ago. It doesn't mention the init method.
> Thanks for taking the time,
> - Karl
> Concurrency-interest mailing list
> Concurrency-interest at cs.oswego.edu
More information about the Concurrency-interest