As far I know "Context Parameters" (defined using the <context-param> element of a deployment descriptor) are accessible from multiple threads simultaneously and from any servlet of the web application.
One of the web-sites claims they are "thread-safe". Maybe I am missing something here... but I thought they are not thread-safe since these are accessible from multiple threads simultaneously
You cannot change the value of context parameters programmatically. Can you?
If you cannot change the value of context-parameters (that are specified in the deployment descriptor using <context-param> ) why is it not thread safe? I think they are thread safe, since they are READ-ONLY. But context attributes are NOT thread safe, I agree with that.
Context is not thread safe for more detail refer SCWCD kit page no. 167
Pawan Ramchandani<br />*******************************<br />SCJP 1.4<br />SCWCD <br />*******************************<br />Everything is okay in the end. If it's not okay, then it's not the end.
Joined: Aug 26, 2004
I am still confused here. I checked page. 167 of SCWCD Study Kit. It says "context attributes" are not thread safe. I agree with that. Obviuosly they are not thread-safe. But why is the parameters in the "<context-param>" not thread safe. Please clarify this.
Thanks in advance.
Joined: Jan 20, 2004
After reading the posts, I kind of tend to agree with Subramonyan.
It would be great if someone else can give his/her input on this.
Any immutable object is threadsafe without any synchronization. This includes context parameters. Or, for that matter, immutable objects that you bind as context attributes at webapp initialisation time - whatever the study kits say.
I think you guys are so confused because you're using the word "threadsafe" in multiple different meanings. To me, "threadsafe" basically means "behaving correctly in a multithreaded environment". If you go with this definition, you cannot really speak of a location (such as context attributes) being "threadsafe" or "thread-unsafe". What you have to say instead is that the objects in that location can be accessed simultaneously by multiple threads, and therefore need to be threadsafe for the system as a whole to be threadsafe.
And immutability is one way to make an object threadsafe. Synchronization is another. The most daring might be using volatile; the most clever Doug Lea's concurrent packages (now part of JDK 1.5, I mean Java 5, or whatever).
And (we're leaving SCWCD territory here) always keep in mind that, if an object is threadsafe, that does not mean that the system that you build around it - what you are doing with the object - is threadsafe. The perennial example is Vector. Vector is "threadsafe", but if you implement a read-modify operation using a Vector, then that operation is not threadsafe even though the Vector is. Which is one of the reasons why ArrayList is so much better than Vector.
- Peter [ September 03, 2004: Message edited by: Peter den Haan ]
Context initialization parameters (from <context-param> are thread-safe by nature because they are read-only (immutable). As Peter said, any characteristic of an object that is immutable is also thread-safe. This is true for all of Java.
Context attributes are a different story. Attributes can be added, retrieved, and removed from the context object. The setAttribute, getAttribute, and removeAttribute methods on ServletContext are not thread-safe. See servlet spec section 10.5 page 83.
Joined: Jan 20, 2004
You said it, Bryan!!
Peter den Haan
Joined: Apr 20, 2000
Originally posted by Bryan Basham: Context attributes are a different story. Attributes can be added, retrieved, and removed from the context object. The setAttribute, getAttribute, and removeAttribute methods on ServletContext are not thread-safe. See servlet spec section 10.5 page 83.
... Which deals with listener classes.
Once again I need to raise the red flag with regards to the use of the word "threadsafe". You are using the word here in a way that I would consider at the very least misleading, at worst plain wrong Stating that "the setAttribute, getAttribute, and removeAttribute methods on ServletContext are not thread-safe" implies that you cannot safely access these methods from multiple threads and need explicit synchronization to prevent this from happening. This, after all, is the meaning of the statement that "ArrayList is not threadsafe", for example.
As you presumably know very well, this is exactly the opposite of the truth. The discussion of listener threading that you referred to a direct consequence of this: "attribute changes to ServletContext and HttpSession objects may occur concurrently", it states. It doesn't get much clearer than that. In order for attribute changes to occur concurrently, the set/get/removeAttribute methods must necessarily be threadsafe in the dictionary definition sense of the word: "a program portion or routine that can be called from multiple programming threads without unwanted interaction between the threads."
I'm not completely sure of what you actually meant to say though. Perhaps it was that these ServletContext methods are multi-threaded? But that's not all that important: application- and session-bound objects would have to be threadsafe regardless of whether the set/get/removeAttribute methods allowed multi-threaded execution or not, simply by virtue of the fact that multiple threads can have a reference to them at the same time.
Maybe I'm just being thick. Can you explain exactly what you meant? Until we unpick the semantic tangle, answers will be neither simple nor definitive and poor folks like Saeed and Sekhar will probably remain terminally confused
- Peter [ September 04, 2004: Message edited by: Peter den Haan ]
Joined: Feb 17, 2004
Peter, I think you are explaining from the perspective of a good programming practice(s). But the point, rest of the guys considered here, is from the 'default nature' perspective and also from 'the exam' perspective.
As per the discussions, context parameters are thread safe. Because you can never modify these values, where as attributes are not thread safe, as we can always update the values. So to make attirbutes thread-safe, either we have to use synchronization or some other mechanism, which will ensure that no two thread can have access to the 'Attributes manipulation statements'.
I think is the point, all the guys (i guess except you) agree with. This is what exactly Brayn also said.
Are you trying to make some other point? If yes, if you can come out with an example, that would be helpful.
From the exam's perspective, context *attributes* are not considered threadsafe, because, as y'all said, multiple threads within the same web app can have access to the *same* attributes.
In fact, the only attributes (for the exam) that are considered technically threadsafe are *request* attributes. Even session attributes, are not guaranteed to be threadsafe, under certain circumstances (client opens a second window in their browser and... it could happen that it's perceived as a different request with the same session ID).
For the exam, you need to recognize which attributes are--and are not--threadsafe, and you can expect to be asked to examine some code and determine if the attributes are protected or not. So you have to be able to answer questions based on thinking... "well, if I DO want my context attributes to be threadsafe, then what can I *do* to protect them?"
Remember, for SCWCD, you do NOT need to be an expert in the most subtle threading issues, but you DO need to understand the implications of how these attributes are stored and who/what part of the system has access, and how you can protect (if needed) those attributes from concurrency problems that might occur when, say,
*Servlet A gets the value of a context attribute Foo, and finds that it is 22 (from Thread A) * Servlet B becomes the currently-running thread and updates the context attribute Foo with a value of "42" (from Thread B) * Servlet A's Thread A comes back as the currently-running thread, manipulates the value it got earlier (adds 10) and then sets the attribute Foo again with the new value. That means Servlet B's "update" is completely lost, as though it never happened.
Synchronizing on the context object would have prevented this problem, while synchronizing on the service() method of Servlet A and Servlet B... would NOT prevent the problem... these are the kinds of things you need to think about for the exam.
Peter den Haan
Joined: Apr 20, 2000
Originally posted by Sekhar Kadiyala: [...] This is what exactly Brayn also said.
No, it certainly is not. Bryan said this:
The setAttribute, getAttribute, and removeAttribute methods on ServletContext are not thread-safe.
This is what I responded to, because as stated it is absolutely false. The exam does not require you to learn things that are not true.
The general point I was trying to make in this thread is that I'm seeing a lot of confusion caused by the word "threadsafe" being used in a very imprecise way (and not just here). I'm happy to accept that I then compounded the problem by offering a definition that was slightly different from that used in the exam; I do apologise. Thanks to Kathy for clarifying that.
That does not mean that the problem I tried to address isn't there! Bryan was kind enough to provide the sterling example quoted above. Something similar can be said for your own statement that
So to make attirbutes thread-safe, either we have to use synchronization or some other mechanism, which will ensure that no two thread can have access to the 'Attributes manipulation statements'.
The 'Attributes manipulation statements' you are referring to can easily be misread to mean HttpSession.getAttribute and so on. A dangerous misunderstanding, because these methods aren't the problem. The objects you bind as attributes are. I have little to add to what Kathy wrote in this thread about it. Please carefully note the way she uses the word "threadsafe".
 I stress as stated because there is no doubt that Bryan knows what he's talking about. I don't think we have an argument on technical matters. [ September 07, 2004: Message edited by: Peter den Haan ]
Peter den Haan
Joined: Apr 20, 2000
Originally posted by Kathy Sierra: [...]Even session attributes, are not guaranteed to be threadsafe, under certain circumstances (client opens a second window in their browser and... it could happen that it's perceived as a different request with the same session ID).
Little anecdote to lighten things up... I did hit this 'in the wild' on a project that uses frames. A browser will request all these frames simultaneously. The problem was that the controller we used stored some request-specific state in the user's session. Most of the time it was fine, but sometimes one subframe messed up another subframe's request and triggered an error. Such subtle threading problems can be hell to track down because they happen rarely and are hard to reproduce.
A lot of developers seem to treat session attributes as if they were threadsafe. Bad habit.
- Peter [ September 07, 2004: Message edited by: Peter den Haan ]
Joined: Apr 30, 2001
Please allow me to provide a code example to demonstrate my point.
The question is: Is this code thread-safe? Meaning will this code behave as excepted (print the next value of counter to the response stream) in a multi-threaded environment? The answer is no, because it is possible that two request hit this servlet. Let's suppose that thread-1 executes through line 13 and is suspended by the JVM; counter=1. The thread-2 executes the whole method; counter=2. Now thread-1 continues and print "counter = 2". That clearly is incorrect behavior; and thus not thread-safe.
So how do we solve this problem? The answer is the synchronize on the critical code of the servlet (which is basically the whole method):
OK, this is easy to see when using an instance variable. Let's change the example to use a context-scope attribute.
I contend a new concurrency problem arises with this code because two thread could read/write the "counter" attribute out of order. Thread-1 reads the counter attribute on line 13 and is suspended by the JVM; counter=0. Thread-2 reads the counter attribute and then increments it (through line 15); counter=1. Thread-1 then continues and increments the local variable counter to 1 and stores that value back to the context attribute. Both requests see the response "counter = 1" which is wrong.
One way to solve this problem (but probably not the best) is to sychronize on the context object:
Notice that the behaviour is slightly different than the first (instance variable) demonstration, but the point is that both servlets fail to act "correctly" under a multi-threaded environment.
Originally posted by Bryan Basham: Please allow me to provide a code example to demonstrate my point.
Bryan, I do appreciate your point; I didn't think we had any differences of opinion in purely technical terms anyway. There is no problem with what is being expressed, just (IMHO) with the way it was put. If "ServletContext.getAttribute() is not threadsafe" means something so totally different from "ArrayList is not threadsafe", something has gone badly wrong with the terms we use, and this will leave many horribly confused about the topic. "Context attributes are not threadsafe", as Kathy put it, is much less ambiguous.
Pedantic? Maybe. It has been my experience that bad terminology is a frequent source of threading confusion. It pays to be pedantic here.
- Peter [ September 08, 2004: Message edited by: Peter den Haan ]
Joined: Apr 30, 2001
Originally posted by Peter den Haan: Bryan, I do appreciate your point; I didn't think we had any differences of opinion in purely technical terms anyway. There is no problem with what is being expressed, just (IMHO) with the way it was put. If "ServletContext.getAttribute() is not threadsafe" means something so totally different from "ArrayList is not threadsafe", something has gone badly wrong with the terms we use, and this will leave many horribly confused about the topic. "Context attributes are not threadsafe", as Kathy put it, is much less ambiguous.
After posting my code examples I realized that I had not truly answer the debate of "ServletContext.getAttribute() is not threadsafe", but rather I answered the debate "changing context-scope variables is not threadsafe." It turns out that these are different questions.
Clearly, calling getAttribute and then setAttribute is not an atomic operation and is not thread-safe (as I demonstrated in my code examples).
However, what about the actual thread-saftey of the getAttribute, setAttribute, and removeAttribute methods, themselves? This question is more closely related to Peter's analogy with ArrayList. The ArrayList.add method is not thread-safe because two threads could be attempting to add an element concurrently. Inside of the add method, the array and counter data of the ArrayList object is being manipulated and it is possible that one thread could be suspended in the middle of changing the state of these datum which would leave the ArrayList object in an inconsistent state.
Similarly, the ServletContext.setAttribute method might be using a Map to store the context-scope attributes. If the setAttribute method is not synchronized or if the Map implementation used by the ServletContext implementation is not thread-safe, then the setAttribute method is also not thread-safe.
But guess what? It turns out that this question is container-specific because the implementation of the ServletContext interface is provided by the container vendor. I asked one of the servlet spec leads, Greg Murray, about this and here is his reply:
Greg Murray: The servlet spec is a bit wish washy on this subject and different implementations may chose to make it safe.
Since the APIs are just the interfaces it really is down to the spec to define what really happens in the implementations.
BluePrints has always recommended writing thread safe code when accessing the Servlet context to maintain portability.
In a follow-up message, Greg told me that Tomcat v5 does in fact synchronize access to the context-scope attributes HashMap. So, for Tomcat, internal data structures inside of its ServletContext implementation are thread-safe. But there is no guarantee that other vendors do this.
Originally posted by Peter den Haan: Pedantic? Maybe. It has been my experience that bad terminology is a frequent source of threading confusion. It pays to be pedantic here.
You are absolutely right, Peter. It is very appropriate to be clear and thorough (if not pedantic) about these issues. When talking about concurrency issues there are many layers to the onion. I think everyone can learn from these discussions.
By the way this discussion proved to be the best in learning Concurrency and Single Threaded Model, problems and solutions. But at the same time it also reveales what can be asked in the real exam. Pretty interesting debate.However in practical terms, I have seen many enetrprise application that are in production but Thread safety was not paid much attention still these proved to be successful applications without any crashing or any performance issue. I know theoratically things turn out to be more atomic and argumentive. It is just like, in theory, every atom is fissionable and may start a chain reaction but in practice there are few isotopes that are capable of doing it. The point is that it is good from learning perspective and every care should be done in the design but practically this is not as scary as it looks. Anyways, this discussion helped. Bryan and team I have already become a fan of your crystal clear understanding of the subject and a great presentation in your book. cheers