|
>My simple model (above) breaks down really fast >in discussions of threads and thread-safe coding. >I'm still trying to grasp the concept of sharing >code with other requests. If a change an instance >variable that is *not* a static, it seems to me >(with my meager understanding of Java) that >it changes for that particular instantiation of the object. >However, the need to make things thread-safe >seems to contradict that assumption. No, you have it right as far as you took it. The big question involved in all this is: "Which threads get to see which objects." That is, who gets a "reference" (a.k.a. a pointer in C or Pascal) to this object. You simply have to know the answer to that to make much progress on this. It's part of the design and should not be a casual choice. Quick referesher on terminology: You construct an object, which is an instance of the object. Usually, an object can have any number of instances (and a variable within an instance is an instance variable). Java does not have pointers, quite, but has "reference variables" which hold something very much like a pointer to the object. If you alter a "reference variable" or "object reference variable", it means you're pointing it at either a new object or no object at all (null pointer, or, more properly, null reference). Now, changing a static (class) variable changes it "machine" wide (actually, JVM-wide). Changing an instance variable only changes the value of that piece of that particular object. The real issue turns out not to be whether it is "machine" wide or "instance" wide relative to threads. The real issue for instance variables in particular (and also static variables in slightly different ways) is which thread or threads get a "reference" to the object and so get a change to view or modify the object "referenced". And, how that is managed. Possible Thread Models vis a vis a particular object instance: 1. Only one thread, ever, sees the object. This is easy. You don't have to synchronize anything and you don't, by definition, have to worry about anyone else looking at the object. The instance variables are "all yours" and you can code about the way we still do in RPG in terms of how you treat instance variables. In terms of servlets, I do this by creating and discarding a "shadow" object. In terms of ordinary applications, you kind of have this by default if you don't launch any threads. Code reuse must be considered, here, as useful objects are sometimes used in new ways (e.g. in the number 4 case below) long after their initial deployment. 2. One thread creates the object and no one thereafter changes it. You don't have to synchronize anything. You may have to spend some thought (from security or some other angle) thinking about what it means for more than one thread to see the object, but that's about it. You don't have to worry about the object changing in nasty (code-breaking) ways, because no one ever changes it after the creating thread hands pointers of it to other threads. Again, the techniques involved are similar to what one is used to in languages like RPG, provided everyone keeps the discipline and does not change the object's instance variables. 3. A less common method: One thread creates the object and then the object is carefully (using synchronized methods) handed from one thread to another. When one hands it to another (or, to a repository), no further use is made of the object by the "hander-offer." Here, you make sure that only one thread at a time deals with the object. In principle, if you handle this sub-model just right, you don't have to synchronize anything but calls to the Vector or Hashtable or whatever you use to hold the object between hand-outs to other threads. A little thought is required to make sure what I just said is true and stays true. My "shadow" object with a "stash" is one example of this. Since returning the "shadow" to a repository would be the last deed before ending the whole servlet doGet invocation, knowing the "hander offer" rule was followed is fairly straightforward. In other cases, this might be a bad idea. 4. One thread creates the object and it's a (controlled) free for all. Any number of threads can view or change the object, concurrently. Here, nearly all methods need to be synchronized. It is easiest if they are synchronized at the "method" level using a keyword, but a few may need the "block" method due to a little added complexity. This is where things get potentially nastiest and buggiest, because you have to worry about some concurrently active thread looking at or changing instance variables within "your" object. This even includes other methods that you, yourself wrote. In fact, it usually does. One trick to understand at the outset is that "looking" is sometimes as dangerous as "changing" in terms of breakage chances. The problem with the servlet object architecture is that it introduces model number four rather needlessly (in my view of it). That complicates things in that people who otherwise can put model number four off for a while cannot, at least not without my shadow trick. I find the instance variables of a servlet object nearly useless and resort to my shadow approach instead so that I can deal with things more or less normally. In applets or ordinary applications, one tends not to have this problem imposed and one can pick any of the above operational models explicitly. My shadow approach restores this for the servlet environment. By the way, for static variables, they tend to end up in model 4 above unless they are static final (and hence follow model 2). Larry W. Loen - Senior Linux, Java, and iSeries Performance Analyst Dept HP4, Rochester MN
As an Amazon Associate we earn from qualifying purchases.
This mailing list archive is Copyright 1997-2024 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].
Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.