You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@struts.apache.org by Amit Badheka <am...@direct2s.com> on 2002/12/20 08:05:22 UTC

multithreaded env

Hi All,

I am working on a struts application. But I am not sure that it will work properly in multithreaded environment.

Can anybody suggest me what is the best way to make sure that application work fine in such environment.

Thank You.

Re: multithreaded env

Posted by Amit Badheka <am...@direct2s.com>.
Hi Andrew,

Thanks a lot for such a great information.
It has cleared lots of my doubts.

But, I will be very thankful if you can put some more light on case if I
want to do serialization or file handling.

thanks.

Amit Badheka.

----- Original Message -----
From: "Andrew Hill" <an...@gridnode.com>
To: "Struts Users Mailing List" <st...@jakarta.apache.org>
Sent: Friday, December 20, 2002 1:50 PM
Subject: RE: multithreaded env


> A webapp running in a servlet container (this includes any struts app) is
by
> nature multithreaded.
>
> As you know, in a struts app most of the work is done not in servlets you
> implement, but rather in Action classes.
>
> These are also multithreaded. Struts will create a single instance of your
> Action and all requests for that Action will be processed by that
instance.
> This means that at any given moment you could have any number of threads
> simultaneously running that Action's code.
>
> The implication of this is that you have to be careful of what you do with
> class member variables. (ie. Dont use them!)
>
> for example, consider the following rather contrived Action:
>
> public class WotsitAction extends Action
> {
>   private String _foo; file://member variable - Dangerous!
>
>   public ActionForward execute(ActionMapping mapping, ActionForm
actionForm,
>                                HttpServletRequest request,
> HttpServletResponse response)
>   throws Exception
>   {
>     WotsitForm wotsitForm = (WotsitForm)form;
>     _foo = wotsitForm.getFoo(); file://line 1
>     doSomething(_foo); file://line 2
>     file://etc....
>   }
> }
>
> Now let us imagine we have two users who both submit different values for
> foo at nearly the same instant. User A submits a value of "A", and User B
> submits a value of "B". Let us assume that user A submits first. The
action
> code is invoked and line 1 causes _foo to be set to "A".
>
> Meanwhile user B has also submitted. His request goes to the same instance
> of the WotsitAction.
>
> Let us imagine that user B's thread executes line 1 a picosecond after
user
> A, just before user A's thread starts line 2. As a result _foo is now set
to
> "B", because both threads are sharing the same action instance and thus
the
> same _foo variable.
>
> Now BOTH users threads will be using the value of "B" to doSomething().
This
> is obviously not what we intended...
>
> Whats rather scary about this is that the errors that will result may well
> not be picked up in your basic testing, but rather will surface much later
> when load testing is conducted, or even worse when the app is in
production.
> They will be intermittent errors and could take a considerable amount of
> time to track down...
>
> In this example for the code to work as intended it is necessary that the
> member variable _foo is replaced by a method variable. Ie:
>
> public class WotsitAction extends Action
> {
>   public ActionForward execute(ActionMapping mapping, ActionForm
actionForm,
>                                HttpServletRequest request,
> HttpServletResponse response)
>   throws Exception
>   {
>     WotsitForm wotsitForm = (WotsitForm)form;
>     String foo = wotsitForm.getFoo(); file://line 1
>     doSomething(foo); file://line 2
>     file://etc....
>   }
> }
>
> In this case both threads still share the action instance, but foo is now
> local to the execute method and each thread has its own foo. Things will
now
> work as intended...
> Basically dont use class member variables in your actions (unless you are
> specifically intending to share information between threads with them.
Even
> in that case it would not be a good idea as you have other such
> considerations as clustering, the need to synchronize reads and writes
> etc...).
>
> Now you may be thinking you could instead of refactoring all that code in
> the first version of WotsitAction just make the execute & other public
> methods synchronized, and indeed you technically could.
>
> That however has nasty performance implications. Imagine the execute()
> method takes 10 seconds to do its thing. Imagine also that 6 users submit
at
> once. With execute synchronized, only one of the threads can be executing
> the synchronized code at a time. Some of those users could be waiting up
to
> a minute for their request to complete... Furthermore thread wakeup
> notification doesnt happen in any particular order. If lots more requests
> keep pouring in all the time its conceivable some request threads could
> 'never' get a chance to run execute()!!!!
>
> These sort of issues need to be considered for any shared objects. For
> example stuff you put into ServletContext can be accessed by many threads
at
> the same time. Likewise with stuff in the SessionContext. The request
> context on the other hand is not shared with other threads (unless you
make
> your own threads - (dont do that in a webapp! - its naughty)). Request
> scoped actionform instances are therefore unique to that request. Session
> scoped actionforms may be 'problematic' under some circumstances. (Refer
to
> my discussion in this list with Eddie recently under the thread "Multiple
> forms in session" to see why)
>
> -----Original Message-----
> From: Amit Badheka [mailto:amit@direct2s.com]
> Sent: Friday, December 20, 2002 15:05
> To: Struts Users Mailing List
> Subject: multithreaded env
>
>
> Hi All,
>
> I am working on a struts application. But I am not sure that it will work
> properly in multithreaded environment.
>
> Can anybody suggest me what is the best way to make sure that application
> work fine in such environment.
>
> Thank You.
>
>
> --
> To unsubscribe, e-mail:
<ma...@jakarta.apache.org>
> For additional commands, e-mail:
<ma...@jakarta.apache.org>
>
>


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


RE: multithreaded env

Posted by Andrew Hill <an...@gridnode.com>.
A webapp running in a servlet container (this includes any struts app) is by
nature multithreaded.

As you know, in a struts app most of the work is done not in servlets you
implement, but rather in Action classes.

These are also multithreaded. Struts will create a single instance of your
Action and all requests for that Action will be processed by that instance.
This means that at any given moment you could have any number of threads
simultaneously running that Action's code.

The implication of this is that you have to be careful of what you do with
class member variables. (ie. Dont use them!)

for example, consider the following rather contrived Action:

public class WotsitAction extends Action
{
  private String _foo; //member variable - Dangerous!

  public ActionForward execute(ActionMapping mapping, ActionForm actionForm,
                               HttpServletRequest request,
HttpServletResponse response)
  	throws Exception
  {
    WotsitForm wotsitForm = (WotsitForm)form;
    _foo = wotsitForm.getFoo(); //line 1
    doSomething(_foo); //line 2
    //etc....
  }
}

Now let us imagine we have two users who both submit different values for
foo at nearly the same instant. User A submits a value of "A", and User B
submits a value of "B". Let us assume that user A submits first. The action
code is invoked and line 1 causes _foo to be set to "A".

Meanwhile user B has also submitted. His request goes to the same instance
of the WotsitAction.

Let us imagine that user B's thread executes line 1 a picosecond after user
A, just before user A's thread starts line 2. As a result _foo is now set to
"B", because both threads are sharing the same action instance and thus the
same _foo variable.

Now BOTH users threads will be using the value of "B" to doSomething(). This
is obviously not what we intended...

Whats rather scary about this is that the errors that will result may well
not be picked up in your basic testing, but rather will surface much later
when load testing is conducted, or even worse when the app is in production.
They will be intermittent errors and could take a considerable amount of
time to track down...

In this example for the code to work as intended it is necessary that the
member variable _foo is replaced by a method variable. Ie:

public class WotsitAction extends Action
{
  public ActionForward execute(ActionMapping mapping, ActionForm actionForm,
                               HttpServletRequest request,
HttpServletResponse response)
  	throws Exception
  {
    WotsitForm wotsitForm = (WotsitForm)form;
    String foo = wotsitForm.getFoo(); //line 1
    doSomething(foo); //line 2
    //etc....
  }
}

In this case both threads still share the action instance, but foo is now
local to the execute method and each thread has its own foo. Things will now
work as intended...
Basically dont use class member variables in your actions (unless you are
specifically intending to share information between threads with them. Even
in that case it would not be a good idea as you have other such
considerations as clustering, the need to synchronize reads and writes
etc...).

Now you may be thinking you could instead of refactoring all that code in
the first version of WotsitAction just make the execute & other public
methods synchronized, and indeed you technically could.

That however has nasty performance implications. Imagine the execute()
method takes 10 seconds to do its thing. Imagine also that 6 users submit at
once. With execute synchronized, only one of the threads can be executing
the synchronized code at a time. Some of those users could be waiting up to
a minute for their request to complete... Furthermore thread wakeup
notification doesnt happen in any particular order. If lots more requests
keep pouring in all the time its conceivable some request threads could
'never' get a chance to run execute()!!!!

These sort of issues need to be considered for any shared objects. For
example stuff you put into ServletContext can be accessed by many threads at
the same time. Likewise with stuff in the SessionContext. The request
context on the other hand is not shared with other threads (unless you make
your own threads - (dont do that in a webapp! - its naughty)). Request
scoped actionform instances are therefore unique to that request. Session
scoped actionforms may be 'problematic' under some circumstances. (Refer to
my discussion in this list with Eddie recently under the thread "Multiple
forms in session" to see why)

-----Original Message-----
From: Amit Badheka [mailto:amit@direct2s.com]
Sent: Friday, December 20, 2002 15:05
To: Struts Users Mailing List
Subject: multithreaded env


Hi All,

I am working on a struts application. But I am not sure that it will work
properly in multithreaded environment.

Can anybody suggest me what is the best way to make sure that application
work fine in such environment.

Thank You.


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>