On Thu, 27 Dec 2001, Nikola Milutinovic wrote:

> Date: Thu, 27 Dec 2001 07:55:50 +0100
> From: Nikola Milutinovic <[EMAIL PROTECTED]>
> Reply-To: Tomcat Users List <[EMAIL PROTECTED]>
> To: Tomcat Users List <[EMAIL PROTECTED]>
> Subject: Re: Clarification needed, please
>
> > > Is it OK to place non-static attributes of the class into
> > > "global declaration" section or should I confine them to
> > > being local variables of the "service()" method?
> > NOOOOOOOOOOOO!.  If you don't want to receive threading problems that
> > become very difficult to diagnose, don't put anything as a static (or
> > instance for that matter) variable. Only use local variables unless you
> > know what you are doing (i.e. they can be used to store configuration
> > information, but be aware of issues involved when one thread changes
> > the configuration while another tries to use it).
>
> (sigh) Thank you for saying it outloud. I've read many online
> tutorials, since my access to books is very limited, but I've never
> seen this kind of explicit explanation. Or at least I missed it. Do
> you know a good book/tutorial? I don't need something that will "take
> me by the hand like an infant". I want something that states facts as
> explicitely as you did, just now.
>

Writing thread-safe code is one of the most mind-bending aspects of
writing server-side applications (rather than client-server GUIs where you
control everything :-).

> > > OK. So, suppose two (simultaneous) requests arive for this
> > > URL. Will there be one instance of the class to handle them?
> > Yes.
>
> I must admit I'm a bit unaccustomed to this idea. I agree that one
> instance may handle the request, if it can. But while the request is
> being handled, I thought that the instance would be "locked for
> access" and that in case of a recursive servlet, Tomcat would
> instantiate as many as needed. My mistake, I guess.
>

There is no locking at all ... or any need for it.

The key is that each simultaneous request will occur on it's own
processing thread, with it's own stack - which contains all the local
variables.  That's why using local variables is safe, and using instance
variables is not.

> > >  Or, better yet, since, the class will open a JDBC
> > > connection, it will be opened twice, *but will be stored in
> > > the same variable*. Effectively, the first one will be
> > > deleted by the garbage collector and closed. I sense a
> > > dangerous situation here.
> > Yes.
>
> So, would something like this be appropriate?
>
> <%!
> Connection conn = null;
> %>
> <%
> synchronized( conn ) {
>   if( conn == null )
>     conn = DriverManager.getConnection( URL, user, pass );
> }
> ...
> // should I delete it?
> synchronized( conn ) {
>   if( conn != null ) {
>     conn.close();
>     conn = null;
>   }
> }
> %>
>
> > > In other words, is it appropriate to place non-static
> > > atributes of the JSP/Servlet in <%! %> section?
> > No.
>
> Or at least not unless I'm willing to synchronize on them.
>

If you want to have an app that scales to lots of users, synchronization
is *not* the right answer.  It implies that, deep down, your app can only
support one user at a time.  This is not appropriate in a web application
world, unless your user population is very very small.

> > > You can imagine how this relates to a recursive Servlet.
> > > Right now I'm seeing this behavior in plain sight. I was just
> > > wandering what is the recomendation or correct practice.
> >

Recursion is not the right design pattern for this kind of application
requirement.

> > You could define a method in the <%! %> and pass the entire context
> > in as parameters and then call that method from your <% %> code blocks.
> > You could also define a class in the <!% %> code blocks that could
> > hold your state and define the method to recurse on.
>
> That's how I tested it :-) Given all circumstances and the fact that
> one careless infinite recursion flooded my DB with connection
> requests, I'll rethink the recursion bit. Due to data structure I
> cannot avoid it, but I really don't need n connection for n-depth
> subtree. Maybe I'll use the code from above, the one with
> synchronization.
>
> Or maybe I should employ connection pooling? Basically, every servlet
> in recursion needs a connection, be it a new one or an existing one
> from the pool...
>

The fundamental problem with the approach you are thinking about isn't so
much thread safey -- it's the fact that you are going to be intermixing
business logic (i.e. *what* does my application present) with presentation
logic (i.e. *how* does it look).  You'd be much better off, IMHO, by
learning how to design your web application according to
Model/View/Controller (MVC) design patterns.  MVC has been around for 30
years or so in GUI-based application designs, and has proven its worth in
helping you create understandable and maintainable application designs.

There are many examples of application frameworsk that help you deal with
these issues.  My favorite (disclaimer:  I'm the primary author, but it's
quite popular so my opinion is not totally biased :-) is the Struts
framework available from Apache:

  http://jakarta.apache.org/struts/

You would do well to study other approaches to dealing with the "multiple
users" isseus -- the path you're going down is going to bite you.

> Nix.

Craig McClanahan



--
To unsubscribe:   <mailto:[EMAIL PROTECTED]>
For additional commands: <mailto:[EMAIL PROTECTED]>
Troubles with the list: <mailto:[EMAIL PROTECTED]>

Reply via email to