In a previous post I wrote:
Frankly, not only is it not thread safe, but the solution doesn’t even make any sense in a multi-threaded environment!
What are you trying to do here? Well, when someone comes along and changes the value, you’d like to tell everyone who cares what that value changed to. Simple enough, right? But in a multi-threaded environment, what does it mean when thread 1 changes the value when thread 2 also wants to change the value? Are the objects who want to be notified thread safe? What does it mean when a central value is changed twice by two threads? What is the semantics here?
I think this is worth clarifying in order to illustrate a basic point.
In the single-threaded single-process environment we’re all used to, the primary question a programmer should ask himself is “what am I trying to accomplish.” That is, if the purpose of the program is to display status in a window, then what you’re trying to accomplish is to display status in a window. Immediately from the above statement of intent, you can see that you’ll need something that gets the status you’re trying to display (a ‘CGetStatus’ class, say), you need a window (a ‘CWnd’ derived class which overrides OnPaint, say), and the usual syntactic and semantic fluff which makes a program, well, a program–such as a ‘CApp’, the code to handle the menu bar and the like. At this point you can start throwing darts at the design model board if you like: observer makes a good pattern, or some sort of timer loop or whatever. At this point even a so-so GUI programmer can visualize the program in his head and start visually laying out the resources and the class relationships.
But in a multi-threaded environment, we’ve added a new dimension: threads. And now we no longer need to just ask ourselves “what am I trying to accomplish”–but (and this is the key part) who (or rather, which thread) is trying to accomplish it?
And that’s why the observer design pattern fundamentally makes no sense in a multi-threaded environment. The observer pattern answers the question “what are we trying to accomplish” (notify listeners when a value changed), but not “who is trying to accomplish it?” So, without knowing ‘who’ (which thread), we don’t know if it’s acceptable to simply run the notification loop re-entrantly (ignoring threads entirely), or if we need to shunt the notification to a Swing UI thread (as was done in my previous example) or create a background thread or threads which handle the notifications.
Until we ask “who is trying to accomplish it”, then shoring up a design pattern (such as the observer pattern) to be “multi-thread safe” is sort of like (well, it actually is) trying to write software without knowing what we’re trying to write.