|
|
Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs
Page 3 of 7
Another kind of misbehavior that may be exhibited in a multithreaded environment by instances of this RGBColor class is read/write conflicts. This kind of conflict arises when an object's state is read and used while in a temporarily
invalid state due to the unfinished work of another thread.
For example, note that during the blue thread's execution of the setColor() method above, the object at one point finds itself in the temporarily invalid state of black. Here, black is a temporarily
invalid state because:
RGBColor object. The blue thread is supposed to turn a green object into blue.
If the blue thread is preempted at the moment the object represents black by a thread that invokes getColor() on the same object, that second thread would observe the RGBColor object's value to be black.
Here's a table that shows a sequence of events that could lead to just such a read/write conflict:
| Thread | Statement | r | g | b | Color |
| none | object represents green | 0 | 255 | 0 | |
| blue | blue thread invokes setColor(0, 0, 255) | 0 | 255 | 0 | |
| blue | checkRGBVals(0, 0, 255); |
0 | 255 | 0 | |
| blue | this.r = 0; |
0 | 255 | 0 | |
| blue | this.g = 0; |
0 | 255 | 0 | |
| blue | blue gets preempted | 0 | 0 | 0 | |
| red | red thread invokes getColor() | 0 | 0 | 0 | |
| red | int[] retVal = new int[3]; |
0 | 0 | 0 | |
| red | retVal[0] = 0; |
0 | 0 | 0 | |
| red | retVal[1] = 0; |
0 | 0 | 0 | |
| red | retVal[2] = 0; |
0 | 0 | 0 | |
| red | return retVal; |
0 | 0 | 0 | |
| red | red thread returns black | 0 | 0 | 0 | |
| blue | later, blue thread continues | 0 | 0 | 0 | |
| blue | this.b = 255 |
0 | 0 | 0 | |
| blue | blue thread returns | 0 | 0 | 255 | |
| none | object represents blue | 0 | 0 | 255 |
As you can see from this table, the trouble begins when the blue thread is interrupted when it has only partially finished
painting the object blue. At this point the object is in a temporarily invalid state of black, which is exactly what the red
thread sees when it invokes getColor() on the object.
There are basically three approaches you can take to make an object such as RGBThread thread-safe:
The most straightforward way to correct the unruly behavior exhibited by objects such as RGBColor when placed in a multithreaded context is to synchronize the object's critical sections. An object's critical sections are those methods or blocks of code within methods that must be executed by only one thread at a time. Put another way, a
critical section is a method or block of code that must be executed atomically, as a single, indivisible operation. By using
Java's synchronized keyword, you can guarantee that only one thread at a time will ever execute the object's critical sections.
To take this approach to making your object thread-safe, you must follow two steps: you must make all relevant fields private, and you must identify and synchronize all the critical sections.
Step 1: Make fields private
Synchronization means that only one thread at a time will be able to execute a bit of code (a critical section). So even
though it's fields you want to coordinate access to among multiple threads, Java's mechanism to do so actually coordinates access to code. This means that only if you make the data private will you be able to control access to that data by controlling access to
the code that manipulates the data.
JVMSimulator and Method.java and search for sychronized. http://www.artima.com/insidejvm/applets/sourcecode.html