|
|
|
Sponsored Link •
|
|
Advertisement
|
RGBColor #1: Ready for a single thread
As an example of a class that is not thread-safe, consider the
RGBColor class, shown below. Instances of this class
represent a color stored in three private instance variables:
r, g, and b. Given the class
shown below, an RGBColor object would begin its life in a
valid state and would experience only valid-state transitions, from the
beginning of its life to the end -- but only in a single-threaded
environment.
// In file threads/ex1/RGBColor.java
// Instances of this class are NOT thread-safe.
public class RGBColor {
private int r;
private int g;
private int b;
public RGBColor(int r, int g, int b) {
checkRGBVals(r, g, b);
this.r = r;
this.g = g;
this.b = b;
}
public void setColor(int r, int g, int b) {
checkRGBVals(r, g, b);
this.r = r;
this.g = g;
this.b = b;
}
/**
* returns color in an array of three ints: R, G, and B
*/
public int[] getColor() {
int[] retVal = new int[3];
retVal[0] = r;
retVal[1] = g;
retVal[2] = b;
return retVal;
}
public void invert() {
r = 255 - r;
g = 255 - g;
b = 255 - b;
}
private static void checkRGBVals(int r, int g, int b) {
if (r < 0 || r > 255 || g < 0 || g > 255 ||
b < 0 || b > 255) {
throw new IllegalArgumentException();
}
}
}
Because the three instance variables, ints r,
g, and b, are private, the only way other
classes and objects can access or influence the values of these
variables is via RGBColor's constructor and methods. The
design of the constructor and methods guarantees that:
RGBColor's constructor will always give the variables
proper initial values
setColor() and invert() will
always perform valid state transformations on these variables
getColor() will always return a valid view of
these variables
Note that if bad data is passed to the constructor or the
setColor() method, they will complete abruptly with an
IllegalArgumentException. The checkRGBVals()
method, which throws this exception, in effect defines what it means
for an RGBColor object to be valid: the values of all
three variables, r, g, and b,
must be between 0 and 255, inclusive. In addition, in order to be
valid, the color represented by these variables must be the most recent
color either passed to the constructor or setColor()
method, or produced by the invert() method.
If, in a single-threaded environment, you invoke setColor()
and pass in blue, the RGBColor object will be blue when
setColor() returns. If you then invoke
getColor() on the same object, you'll get blue. In a
single-threaded society, instances of this RGBColor class
are well-behaved.
|
Sponsored Links
|