eric leung wrote:

> I have a servlet implements the SingleThreadModel
> Interface. But this servlet has problem handle more
> than 1 request at a time.
>
> Since I have 1 person on host1 upload a big file ( >
> 20MB ) to the servlet.  When the 2nd person on host2
> send a request to that servlet. The servlet will not
> response.
>
> Any one had the same problem using SingleThreadModel?
> I am using apache 1.3.17 + tomcat 3.2.1.
> thanks.
>
> P.S. I use SingleThreadModel beause i don't want to
> worry about syncronization of threads, I have
> Connection as instance variable:
>
> public class admin extends HttpServlet implements
> SingleThreadModel{
>   private PrintWriter out;
>   private OracleConnectionCacheImpl pool;
>   private Connection conn;
>   private Statement stmt;
>
>   ..etc...
> [...]

Hi :-)  from several emails in Servlet-List and this List, perhaps
it is better Not to use the following:
 - SingleThreadModel
 - public synchronized void service/doGet/doPost(...){...}

   (the above two are simialr)


*0  because in fact, the above 2 all use "this(instance) of MyServlet"
      to lock the code, But if:
 - we have more than one servlet-defination in WEB-INF/web.xml,
   now in fact we can not be sure about the "synchronized"
- if  the Servlet container supports "instance pool" for
SingleThreadModel,
  we also can not be sure about the "synchronized".
- if  the Servlet container Doesn't support "instance pool" for
SingleThreadModel,
   now perhaps the performence is not good if we use SingleThreadModel

*1  so I guess the shortcoming of the above 2 are:
- lock All code in service/doGet/doPost, in fact, perhaps we don't need
   to lock all of them
- in some cases, even if MyServlet implememts SingleThreadModel, we
  still can not be sure about "synchronized"(discussed in *0)

*2  so I suggest: perhaps it is better to use a "locker" to "lock and
only-lock" the
      code segment which must to be locked -> we don't need to lock all
the code,
      so now I need a locker: for example, we can use the following as a
locker:
  - a instance field or a static field in MyServlet:
     %private (static) byte[] locker=new byte[0];
     %private (static) Object  locker=new Object();
  - "this"(the instance object of MyServlet)
  - "this.getClass()"(the Class object of MyServlet in webapp
classloader,
     with TOMCAT, and if omitting the auto-reloading, it is Only-One)
  - ServletContext, with TC, it is Only-One within webapp.
  - MyHelper class
     % its instance(SingleTon or Non-SingleTon)
     % its Class object
     % its instance/static field


*3 the following are good emails :-)

*********************************** email0 ********************
See intermixed.

Bo Xu wrote:

> Gokul Singh wrote:
>
> > ----- Original Message -----
> > From: "Bo Xu" <[EMAIL PROTECTED]>
> >
> > >   *  SingleThreadModel is non_multi-thread: so it is thread-safty
but it
> > is not
> > >        multi-thread-safty.  But we also can think it is the safest
way of
> > >       multi-thread-safty :-)
> >
> > Single thread model is thread safe for the member variables of a
class, but
> > as the container *may* instantiate more than one instance, it is not
thread
> > safe for static variables, if any. Another fallback of this is if
you are
> > using a non static member variable, each instance will have it's own
copy
> > which may cause some problems e.g. if you used it to keep count of
the
> > number of hits.
> >
> >  >    *  I guess if we use SingleThreadModel, the Servlet container
> >  >        will have to work *harder*, and the efficacy is
lower(because
> >  >        now for a Servelt class which implements
SingleThreadModel,
> >  >        at any time, only zero/one client can access it ). and
from
> > several
> >  >        emails, it is not good to use SingleThreadModel in a *real

> >  >        system*-> it is for testing(?) or other purpose.
> >
> > In a real environment, there can be N number of requests being
processed
> > simultaneously by a servlet (each being a seperate thread). But if
you use
> > SingleThreadModel, you limit the number of simultaneous request
being
> > processed to the number of instances created by the container, which
can
> > even be 1 !.
> >
> > > Bo
> >
> > Regds,
> > Gokul
> > [...]
>
> Hi Gokul,  thanks for your email! :-)    the following is my new
understanding
> of SingleThreadModel  after I read your email:
>
> # if my Servlet class implements SingleThreadModel, then for every
Servlet
> definition,
>    Servlet container will make a instance pool(which includes n
instances) from
> my
>    Servlet class.
>

More precisely, the servlet container has the *option* to create such a
pool -- it
is not required.  For example, Tomcat only creates one instance of your
servlet per
servlet definition, even if it implements SingleThreadModel.

>
> #  so now:
>         * Servlet container will use one instance in this pool to make
a thread
> for
>            a new client accessing
>         * and in any time( define by Newton, not by Einstein:-) ),  we
can not
> find
>            two threads which are from the same instance.
>         * we will not have n+1 threads in any time.
>
> #  so in fact SingleThreadModel is still similar with multi-thread,
but is a
> *limited*
>     multi-thread-> every thread must from different instance in that
pool.
>

The easiest way to understand what SingleThreadModel does is to pretend
that you
declared your doGet() and doPost() methods to be synchronized -- within
any one
instance of your servlet, there will be at most one request active at
any given
time.

Obviously, this will have performance impact if your container provides
"N"
instances and you get "> N" simultaneous requests.

>
> Is the above right? please give me some directions!
>

My advice:  do not use SingleThreadModel.  My reasoning is this:

* The performance impact described above, when you have more
  requests than instances.

* The synchronization that is performed to implement SingleThreadModel
  is not free -- but you pay that price on every single request even if
it
  is not needed.

* SingleThreadModel gives you the *llusion* of thread safety, because
you
  can use instance variables in your servlet to store per-request state
  information safely.  However, it does not protect you from other
multi-thread
  concerns:

  - Static variables in your servlet class are still accessible from
multiple
    threads at the same time, if your container has instance pooling.

  - Sessions and their attributes can still be accessed from multiple
    requests simultaneously, so you still have to worry about it.

* Locking at the doGet() or doPost() method is more coarse-grained than
  most applications really need.  In most cases, you only really need to

  lock around simultaneous access to shared resources -- but
SingleThreadModel
  doesn't give you that option.

* Instance pooling is not a required feature means that my
  application will behave very differently on containers that provide
instance
  pools versus those that do not.

The best approach is to write your servlets in a thread-safe manner in
the first
place -- then the only limit on how many simultaneous requests you can
handle is
the maximum number of threads your JVM will support, with no artificial
restrictions because of synchronization at the per-servlet-instance
level.

>
> Thanks in advance!
>
> Bo
> Dec.08, 2000
>

Craig McClanahan

*********************************** </email0> ********************

*********************************** <email1> ********************
On Fri, 23 Mar 2001, Pradeep Kumar wrote:

> The Servlet specification says that, that the container should
guarantee only
> one instance of the servlet. However some of the container do maintain
a
> small of pool of servlet instances and manage them. For example there
are 3
> instances of a servlet in the pool, and if there are 300 requests,
each
> instance spawns off 100 threads for 100 requests.
> I don't know how far this is true with Tomcat. In general you should
not make
> any assumptions about the number of instances of your servlet.
>

Maintaining instance pools is *only* allowed for servlets that implement

the SingleThreadModel interface.  Otherwise, the container is required
to
provide exactly one instance of the servlet per servlet definition
(i.e. either the <servlet> declaration in your web.xml file, or a
dynamically created definition when you call /servlet/{servletname}).

Tomcat does not currently implement instance pooling for
SingleThreadModel
servlets, although it could legally do so.

> pradeep
>

Craig McClanahan
*********************************** </email1> ********************



Bo
Apr.13, 2001



Reply via email to