On Thu, Apr 13, 2017 at 6:56 AM, Edward Burns <edward.burns_at_oracle.com> wrote:
> On Apr 11, 2017, at 4:43 PM, Stuart Douglas <sdouglas_at_redhat.com> wrote:
>
> [...]
>
> SD> The formal Java Memory Model reasoning (see
> SD> http://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html#jls-17.4.5
> SD> )
>
> SD> According to the model the two bits we are interested in is:
>
> SD> (1) If x and y are actions of the same thread and x comes before y in
> SD> program order, then hb(x, y).
> SD> (2) If hb(x, y) and hb(y, z), then hb(x, z).
>
> SD> And from the Servlet spec we have:
>
> SD> (3) After the servlet object is instantiated, the container must
> SD> initialize the servlet before it can handle requests from clients.
>
> SD> If we define the following actions:
> SD> A - The field write in the init method
> SD> B - The init method completing
> SD> C - The service method being invoked
>
> SD> We know that we have the following:
>
> SD> hb(A, B) - the field write has to happen before the init method
> SD> completes, as per (1)
> SD> hb(B, C) - init is finished before calling service(), as per (3)
>
>>>>>> On Tue, 11 Apr 2017 17:35:52 -0700, Shing Wai Chan <shing.wai.chan_at_oracle.com> said:
>
> SW> My question is on hb(B, C).
> SW> From 17.4.5, we can have hb(B, C) if
> SW> (i) B and C are on the same thread and B comes before C
> SW> (ii) B synchronizes-with a following action C
> SW> (iii) there is a D such that hb(B, D) and hb(D, C)
> SW> (iv) B before Thread.start().
>
> SW> Since B and C may be on different threads, we only have (ii) and (iii).
> SW> ( (iv) may require using new thread for those requests. This may be not easy to do.)
> SW> (ii) may request a synchronization/lock. Is it a concern here?
> SW> Or can we find D and use (iii)?
>
> Can't we look at (3) as our D? Or, to re-list Stuart's sequence of
> events:
>
> SD> If we define the following actions:
> SD> A - The field write in the init method
> SD> B - The init method completing
>
> B' - The container guarantees that init has completed and has returned
> before C.
>
> SD> C - The service method being invoked
>
> So, then we have hb(A, B) and hb(B, C). But we also have hb(B, B')
> and hb(B',C).
Sure that is another way of looking at it. At the core of it there is
just no correct way to code this so that there is no happens-before
between init() and service(), without either:
- Allowing init() to be called twice
- Allowing init() to still be running when service is called
- Doing something really silly (e.g.have your threads wait in a busy
loop on a non volatile field until init() is complete, which may work,
or may loop forever).
Stuart
>
> Thanks,
>
> Ed
>
>
> --
> | edward.burns_at_oracle.com | office: +1 407 458 0017
> | 7 business days until planned start of Servlet 4.0 Public Review