This week's book giveaway is in the Servlets forum.
We're giving away four copies of Murach's Java Servlets and JSP and have Joel Murach on-line!
See this thread for details.
The moose likes Servlets and the fly likes multiple get requests - one thread serving them all? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Murach's Java Servlets and JSP this week in the Servlets forum!
JavaRanch » Java Forums » Java » Servlets
Bookmark "multiple get requests - one thread serving them all?" Watch "multiple get requests - one thread serving them all?" New topic
Author

multiple get requests - one thread serving them all?

Maciej Drozdzowski
Ranch Hand

Joined: Dec 30, 2009
Posts: 40

i've been studying for scwcd and i'm just warming up now.

the book - head first servlet & jsp - says that each request runs in a separate thread. so i'm putting breakpoints in my servlet's get/post methods to see hwo it works.

i put the beer selection app into an eclipse project, but changed the method to get - and if requests are identical - namely i'm submitting the form with the same param - only one thread is running. if the params are different for multiple requests, then each request has a thread.

i'm running it on tomcat 6.0.20.

i tried another app


with the servlet almost empty



and it's called this way:



if i open the link to a few tabs, it get's only one thread - request 2 waits for request 1 to complete and so on.

what am i doing wrong? do i need to configure tomcat in a different way. i guess this thread-per-request thing is a part of the spec, so it should run this way by default.

any help appreciated.
Bear Bibeault
Author and ninkuma
Marshal

Joined: Jan 10, 2002
Posts: 60766
    
  65

Most likely the browser is returning a cached response.


[Asking smart questions] [Bear's FrontMan] [About Bear] [Books by Bear]
Maciej Drozdzowski
Ranch Hand

Joined: Dec 30, 2009
Posts: 40

ok, that sounds reasonable, request and response objects are the same (determined by object id) each time, but how do i avoid it? of course, disabling caching is not a solution.

let's assume i do some time-constly operations in my doGet method. each request has to wait a certain amount of time.
how can i force requests to use new threads?

or maybe what i'm doing here is just soem sort of anti-pattern?
William Brogden
Author and all-around good cowpoke
Rancher

Joined: Mar 22, 2000
Posts: 12759
    
    5
how can i force requests to use new threads?


You don't have to, Threads are managed by the container, typically there is a Thread pool so the container does not have to create a noew Thread object, it just assigns one that is free. The same Thread may in its lifetime process many requests but it only has the context for one request at a time.

Bill

Maciej Drozdzowski
Ranch Hand

Joined: Dec 30, 2009
Posts: 40

ok, but still ony one thread is active, and until one request is served, next requests are waiting.
so how do i force the container to take more threads from the pool and assign them to requests?
Ulf Dittmer
Marshal

Joined: Mar 22, 2005
Posts: 41078
    
  43
ony one thread is active, and until one request is served, next requests are waiting.

How are you determining that? The code you posted probably finishes so quickly that the response has been returned before you even have a chance of sending the second request.


Ping & DNS - my free Android networking tools app
Maciej Drozdzowski
Ranch Hand

Joined: Dec 30, 2009
Posts: 40

Maciej Magic wrote:so i'm putting breakpoints in my servlet's get/post methods to see hwo it works.

if i open the link to a few tabs, it get's only one thread - request 2 waits for request 1 to complete and so on.


perhaps i didn't make myself clear.

the breakpoint is in the method, i open my link in a new tab - and the breakpoint works. i don't let it go, i'm just opening the link a few more times. and nothing happens, no new stacks, i just have to let the first request go, then it stops again.

there's no such thing in case of different post requests, i open 3 tabs, i hit submit in all of them, i get 3 stacks in eclipse.
Bear Bibeault
Author and ninkuma
Marshal

Joined: Jan 10, 2002
Posts: 60766
    
  65

Maciej Magic wrote:disabling caching is not a solution.

Of course it is. It's quite routine to send response headers that disable browser caching of dynamic resources such as servlets and JSPs.
Maciej Drozdzowski
Ranch Hand

Joined: Dec 30, 2009
Posts: 40

what i meant was disabling caching by toggling browser's options, i'm not familiar with such a kind of response header yet.

will that solve the problem? will really each request be handled by a separate thread?
Bear Bibeault
Author and ninkuma
Marshal

Joined: Jan 10, 2002
Posts: 60766
    
  65

I'm still not sure why you think that this is a threading issue. You're only seeing one thread because you are only submitting one request. The browser is simply serving the same cached response without consulting the server for the others.

Adding the no-cache response headers will tell the browser that you don't want the responses cached in the first place.

See FAQ for information on these headers. A servlet filter is a great place to set them.
William Brogden
Author and all-around good cowpoke
Rancher

Joined: Mar 22, 2000
Posts: 12759
    
    5
You are imagining a problem where there is none. The entire servlet API is engineered to keep interference between requests and between applications to a minimum.

The servlet API guarantees that each request gets its own Thread, request object and response object - not visible to any other. Of course bad programming practice can cause interferences between requests and applications but the architecture supplies the basics for keeping them separate.

Bill
Maciej Drozdzowski
Ranch Hand

Joined: Dec 30, 2009
Posts: 40

Bear Bibeault wrote:I'm still not sure why you think that this is a threading issue. You're only seeing one thread because you are only submitting one request.


no, i'm submitting many requests, but they're identical. they should be served simoultaneously, not in a FIFO manner.

William Brogden wrote:Of course bad programming practice can cause interferences between requests and applications but the architecture supplies the basics for keeping them separate.

where is the bad practice in this case?

i still dont see what i;m doing wrong.
how come they wrote in the book that every request gets a thread and they mentioned no info about response headers?
Bear Bibeault
Author and ninkuma
Marshal

Joined: Jan 10, 2002
Posts: 60766
    
  65

Maciej Drodel wrote:
Bear Bibeault wrote:I'm still not sure why you think that this is a threading issue. You're only seeing one thread because you are only submitting one request.

no, i'm submitting many requests, but they're identical. they should be served simoultaneously, not in a FIFO manner.

So you are actually seeing all the requests being executed in a serial manner? How would you know? Breakpoints in a debugger will not give you reliable info. That's an artificial environment that will not reflect what happens in a real scenario.

William Brogden wrote:Of course bad programming practice can cause interferences between requests and applications but the architecture supplies the basics for keeping them separate.

where is the bad practice in this case?

Turn down your defense-o-meter. He didn't say you were using poor practices; he said that poor practices are the only way for the multiple threads to interfere with each other.

how come they wrote in the book that every request gets a thread and they mentioned no info about response headers?

Every request does get its own thread. And when talking about threading, the cache response headers don't come into play. There are two separate topics being discussed here: threading and caching.
Satya Maheshwari
Ranch Hand

Joined: Jan 01, 2007
Posts: 368
You could consider this for preventing caching:



Thanks and Regards
Maciej Drozdzowski
Ranch Hand

Joined: Dec 30, 2009
Posts: 40

Bear Bibeault wrote:Turn down your defense-o-meter. He didn't say you were using poor practices; he said that poor practices are the only way for the multiple threads to interfere with each other.

it's not any defense, i dont have a problem with people showing me my bad practices, i just want to know the good ones

Bear Bibeault wrote:
Maciej Drodel wrote:
Bear Bibeault wrote:I'm still not sure why you think that this is a threading issue. You're only seeing one thread because you are only submitting one request.

no, i'm submitting many requests, but they're identical. they should be served simoultaneously, not in a FIFO manner.

So you are actually seeing all the requests being executed in a serial manner? How would you know? Breakpoints in a debugger will not give you reliable info. That's an artificial environment that will not reflect what happens in a real scenario.


so what i did now, i ran this code in a regular way, no debugger:


only one request is served.
no caching can help here, app is just stuck in the first request, only one starting message shows up, no other requests are served.
William Brogden
Author and all-around good cowpoke
Rancher

Joined: Mar 22, 2000
Posts: 12759
    
    5
Are you perhaps using the SingleThreadModel interface in your servlet?

Bill
Maciej Drozdzowski
Ranch Hand

Joined: Dec 30, 2009
Posts: 40

no, of course not, that would be too obvious

this is the whole thing:
Jaikiran Pai
Marshal

Joined: Jul 20, 2005
Posts: 9929
    
158

Have you by any chance, changed the default Tomcat HTTP Connector settings? Like the "maxThreads" or "executor"?

[My Blog] [JavaRanch Journal]
Maciej Drozdzowski
Ranch Hand

Joined: Dec 30, 2009
Posts: 40

nope, i changed nothing, it's just a default installation.

when i tried with different requests, many threads ran.

it looks like each kind of request has its own thread - three same requests with parameter 'a' are executed in a serial manner, but that request with parameter 'b' is executed by another thread.
Jaikiran Pai
Marshal

Joined: Jul 20, 2005
Posts: 9929
    
158

Maciej Drodel wrote:
it looks like each kind of request has its own thread - three same requests with parameter 'a' are executed in a serial manner, but that request with parameter 'b' is executed by another thread.


That's really weird. Just to rule out any environmental issues - are you using Tomcat alone or are you fronting it with HTTPD?
Maciej Drozdzowski
Ranch Hand

Joined: Dec 30, 2009
Posts: 40

tomcat alone.
i didn't even start to play with any settings or features yet.

could the fact that my xp is x64 be any problem?
Bear Bibeault
Author and ninkuma
Marshal

Joined: Jan 10, 2002
Posts: 60766
    
  65

In reading through this, you seem to be saying two different things with regards to the submitting the same URL:

1) You are seeing only the first of the requests executing on the server
2) You are seeing multiple requests executing in serial (again, how would you know that they are serial?)

Which is it?
William Brogden
Author and all-around good cowpoke
Rancher

Joined: Mar 22, 2000
Posts: 12759
    
    5
As I recall, each Tomcat Thread gets a unique name. We should be able to see if it really is the same Thread by adding:



To those System.out.print statements.

I also suggest using the Management app which comes with Tomcat 6.0.20 - note you will have to configure tomcat-users.xml to provide for a user in the "admin,manager" roles. The manager app will show the state of each request Thread in the Thread pool that has ever been used.

Bill
Mark E Hansen
Ranch Hand

Joined: Apr 01, 2009
Posts: 643
I really hope I'm not too far out of line here, but I've been watching this thread and a couple things stick out to me.

First, testing the threading by setting a breakpoint in the debugger seems wrong. The debugger is going to cause things to work differently.
Second, testing by having one thread do a cpu-intensive loop seems wrong, as this may cause the machine to become so busy, that it can't manage its resources properly.

Why not try this: In the application method, do a delay loop by sleeping for a reasonable delay period, say 30 seconds, using Thread.sleep()?

Then, run the application in the actual environment (not in the debugger) and see what happens when you make multiple requests from different clients.

Best Regards,
Maciej Drozdzowski
Ranch Hand

Joined: Dec 30, 2009
Posts: 40

Bear Bibeault wrote:In reading through this, you seem to be saying two different things with regards to the submitting the same URL:

1) You are seeing only the first of the requests executing on the server
2) You are seeing multiple requests executing in serial (again, how would you know that they are serial?)


i'm submiting the same url, in many firefox' tabs, many times. now i wrote about the first one only because of the infinite loop. before, they (requests) were short, so request 1 was executed, then request 2 was executed etc - in a serial manner.
my point is - only one request is executed at a time, they are not handled concurrently.

William Brogden - i did check the manager app, it didnt give me anymore info than my small logging.

Mark E Hansen wrote:
Why not try this: In the application method, do a delay loop by sleeping for a reasonable delay period, say 30 seconds, using Thread.sleep()?

Then, run the application in the actual environment (not in the debugger) and see what happens when you make multiple requests from different clients.

i took your advice, still the same thing - all requests handled in a serial way by one thread, one at a time. the interval is 30 seconds.

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {

String name = Thread.currentThread().getName();;
System.out.println( "doGet start " + name );

try {
Thread.sleep( 30 * 1000 );
} catch (InterruptedException e) {
e.printStackTrace();
}

System.out.println( "doGet done " + name );
}


what hit me was that you aksed me to use different clients - first, i wanted to refuse - i just want it to work when i open the link in different tabs.
but then i ran it in IE - and guess what, works concurrently
yes, i cleared firefox' cache, no difference.
what the hell is wrong with firefox?
i guess i will have to try to install a different version.
Mark E Hansen
Ranch Hand

Joined: Apr 01, 2009
Posts: 643
Maciej Drodel wrote:what hit me was that you aksed me to use different clients - first, i wanted to refuse - i just want it to work when i open the link in different tabs.
but then i ran it in IE - and guess what, works concurrently
yes, i cleared firefox' cache, no difference.
what the hell is wrong with firefox?
i guess i will have to try to install a different version.


What I was thinking is the client may be the one holding up the request, not the servlet. I know that some browsers treat all open windows as the same client with regard to requests, while others treat each open window as a separate client instance. It's been too long for me to remember the details.

Basically, if the issue is whether or not your customers requests will be sequential, I think you can see they will not.

I hope this helps,
Maciej Drozdzowski
Ranch Hand

Joined: Dec 30, 2009
Posts: 40

Mark E Hansen wrote: Basically, if the issue is whether or not your customers requests will be sequential, I think you can see they will not.

yup, i got it now.

the question is why is firefox faulty here
William Brogden
Author and all-around good cowpoke
Rancher

Joined: Mar 22, 2000
Posts: 12759
    
    5
It sounds like the Firefox designers are attempting some sort of optimization by queuing duplicate requests.

Thanks for letting us know the resolution of the problem, just another example of how very different programming for the web is from programming for the desktop.

Bill
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: multiple get requests - one thread serving them all?
 
Similar Threads
Multiple Modules - Help?
Chapter 2 (HFSJ) notes , may be useful for anyone
tomcat 7 encounters LifecycleException caused by java.lang.UnsupportedClassVersionError
The server maintains one servlet instance per name?
Stuck on HelloWorldServlet