I wanted to get input on a matter of thread safety for a servlet that processes online tests. The basic question is, "Should I implement the SingleThreadModel on the servlet since many students maybe trying to submit their tests symultaneously for processing?" The servlet does contain three instance variables which perhaps need to remain as such so that an inner class and statements in the doPost(...) method have access to them. Please advise if changes are necessary.
Servlet Structure and Business Logic:
The servlet contains two inner classes named Answer and XMLAnswerHandler. A backend database contains the answers to the tests in the form of xml markup. To process an online test, in the doPost(...) method, I read in the xml data from the database using the XMLAnswerHandler class which implements org.xml.sax.helpers.DefaultHandler. XMLAnswerHandler is used to create an instance variable ArrayList named "answers" to contain multiple instances of class Answer. Class Answer contains an item identifier and the actual answers to a particular test question (item). Also, in the doPost(...) method I load up another instance variable ArrayList named "studentAnswers" again with multiple instances of class Answer. I then, compare the answers given by the student with the answers in the answers ArrayList to determine a final score.
The servlet is as follows:
[EDIT by Dave to break long lines] [ September 09, 2005: Message edited by: David O'Meara ]
The SingleThreadModule is depreciated. It actually doesn't do much to ensure thread safety, despite the name. It is basically the same as synchronizing your service methods.
“Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning.” - Rich Cook
Originally posted by Paul Bourdeaux: It is basically the same as synchronizing your service methods.
Not exactly. With SingleThreadModel (STM) a new instance is created for each request. In the case of Tomcat servlet instances are pooled which makes STM quite fast. In either case, each request doesn't need to wait for the previous one to finish before entering the service method, which would be the case if the service method were synchronized.
The more important is issue is that it's deprecated. That should be enough to answer the original question, (to use or not to use). [ September 09, 2005: Message edited by: Ben Souther ]
Ok, so if SingleThreadModel is depicated, then for sure that eliminates one of my options. So, as it stands now, the servlet is not thread safe. I have those three instance variables there that need protecting!
An option came to mind and perhaps you can confirm. From what I've read, local variables are always thread safe. Would I be able to solve my problem by moving my instance variables and the class XMLAnswerHandler into the doPost(...) method? That way both would be local to the method and XMLAnswerHandler would still be able to see the variables "answers", "studentAnswers", and "QuestionCount".
Joined: Sep 24, 2003
Dang! I tried my own suggestion by moving the XMLAnswerHandler class into the doPost(...) method and the instance variables also. The compiler then complained that the instance variables had to be declared final in order to have the XMLAnswerHandler class use them. However, that makes the variables read-only. That's no good for me. Its the XMLAnswerHandler class that is supposed to set those variables!
I haven't gone through all of your code, so I might have misunderstood what you are trying to do. My understanding is that you want to parse the XML, and get a list of answers and studentAnswers, right? If yes, you could move the answers and studentAnswers inside your XMLAnswerHandler. Like this
Then in your doPost, you do like this
Does that work for ya? [ September 09, 2005: Message edited by: Jayesh Lalwani ]
Joined: May 24, 2004
Originally posted by Ben Souther:
Not exactly. With SingleThreadModel (STM) a new instance is created for each request.
You are, of course, correct Ben. This is actually the second time you have corrected me on that... you would think I would remember sooner or later! Thanks for clarifying for me.
Joined: Sep 24, 2003
You were on the right track. I wound up making the inner class not an inner class. I just made it a normal class and loaded the variables inside it and provided accessor methods like you suggested. The main objective was to try to keep all my variables local to the doPost() method for the sake of thread safety.