• Post Reply Bookmark Topic Watch Topic
  • New Topic

With global variables, threads, and a really sore head! :)

 
Simon Harvey
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi
I was wondeirng if anyone could explain why I cant have the request and response objects in a typical servlet, assigned to global variables.
As I understand it, its something to with threads, but I dont understand why the request and response objects being accessed by threads concurrently is any different than any other variable being accessed byt threads. You can have other variables "up top" so that they can be accessed by all methods, so why not the response and request values.
I dont really get how the servlet makes sure that different requests dont get mixed up. As I understand it the servlet engine issues a thread for each request. That means surely that each thread could interfere with one another - over writting each others semi-complete work?
Is there some sort of synchronisation built in that we dont have to worry about?
I'd really appreciate any explanation that anyone can offer of this. Its a really interesting subject but I havent been able to get the threads concept nailed down yet.
Take care all
Simon
 
Dave Landers
Ranch Hand
Posts: 401
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Each request is processed by a thread. This just means that many requests can be processed at the same time.
Also, the servlet spec says that the servlet container can use any instance of the servlet object for these multiple threads. That lets the servlet engine be more efficient (fast).
The result for servlet developers is that we can not put read/write shared data in fields of the servlet object. The object can be reused by multiple threads at the same time, so this data will be "stomped on" by other threads. All data must be maintained as method-local variables.
So when you are writing your servlet, it all starts with the service method (or doGet or doPost or whatever). If you call other methods from there, you need to pass all the data around as method arguments and do not save it in the servlet object.
In this regard, the request and response objects are no different than any other value - don't save them as fields of the servlet object.
There are several ways in which you can save data for a single user or request - you can use the HttpSession to save user data between requests or you can use the Attributes on the request to save data for the duration of a single request.
The servlet API does have a SingleThreadedModel interface. If your servlet implements this interface, it instructs the servlet container not to share instances between threads. You can use this if you absolutely must put fields on your servlet object. But it is better not to do that as this really limits the performance of your server.
 
Simon Harvey
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi guys,
Thanks for your help. Now this is really important that I understand what you are saying:
For the large part, DONT use global variables? I have a mid sized servlet and I have a lot of variables declared globally. Its just for a uni assignment so multiple people havent got to access it. This is obviously why I havent been getting stupid results. Is that correct?
Am I really supposed to pass any variables around my servlets as parameters? I have lots! That sounds really ugly! :-(
I'm worried now

What I still dont get though is why declaring them within methods makes any difference. If the CPU decides on a context switch half way though a method and gives another thread control, then why are we assuming it wont copy over *method* data. The problem still exists, so I dont know what to do!
Please help!
Thanks all
Simon
 
William Brogden
Author and all-around good cowpoke
Rancher
Posts: 13078
6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes, that is what we are saying. DON'T use global variables or instance variables for anything that changes or is specific to a particular user. Global or instance variables are ok for things that don't change on a per user basis.
It is a big conceptual jump, but you have to make it in order to write servlets.
Your architecture won't resemble typical single user architecture. So you have lots of variables - write one or more helper classes to hold the variables, that way you just pass one reference and store just one variable in the session. (think JavaBeans!)
A variable reference declared inside a method exists ONLY in the Thread stack for that method. If another Thread calls that method, it gets its own new version of the reference it its stack. In a servlet environment any number of Threads can be executing a method "at the same time" with no interference IF you write your code right. Java GC cleans up after you when your Thread exits the method.
Bill
 
Simon Harvey
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,
Your architecture won't resemble typical single user architecture. So you have lots of variables - write one or more helper classes to hold the variables, that way you just pass one reference and store just one variable in the session. (think JavaBeans!)

Thanks for that Bill. I was wondering if you could provide me with a couple more breif explanations.
The first is, when you say that you use a helper class to hold all the variables, how do you do that? Could you give me a really simple example or something? I do have a helper class for what Im trying to do. What it contains is a doHeader/Footer() and a getConncetion().
I dont know what else I could put in it though. The sorts of variables I have are things like candidateNo, candidateName, questionsAnsweredCorrectly and questionsLeft.
As you can maybe tell, I'm making an online test system.

The other thing is, do you only use global variables when you want to share information between threads? How else might you share information? Is there any preffered way?
Thanks so much to Bill and anyone else who can advise. It really is much appreciated.
Kind regards
Simon
 
William Brogden
Author and all-around good cowpoke
Rancher
Posts: 13078
6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ah - the online test system architecture - I have built several recently. A "helper" class to hold the present state of an individual user as he/she passes through the test is certainly a good idea. If you make it serializable than you can write it out to a file so your user can resume the test if they get cut off.
A helper class for writing HTML - as in your doHeader/doFooter idea also is useful, but obviously you don't need one instance per user.
Certainly you can use "global" (really instance or static) variables to hang on to data that every request Thread needs access to.
Bill
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!