The Artima Developer Community
Sponsored Link

Designing for Thread Safety
Using Synchronization, Immutable Objects, and Thread-Safe Wrappers
by Bill Venners
First Published in JavaWorld, July 1998

<<  Page 2 of 11  >>

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:

  1. RGBColor's constructor will always give the variables proper initial values

  2. Methods setColor() and invert() will always perform valid state transformations on these variables

  3. Method 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.

<<  Page 2 of 11  >>


Sponsored Links



Google
  Web Artima.com   
Copyright © 1996-2014 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use - Advertise with Us