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 6 of 11  >>

Advertisement

Approach 2: Immutable objects
An alternative way to make an object thread-safe is to make the object immutable. An immutable object is one whose state can't be changed once the object is created.

Immutable objects are, by their very nature, thread-safe simply because threads have to be able to write to an object's instance variables to experience a read/write or write/write conflict. Because no methods (only the constructor) of an immutable object actually write to the object's instance variables, the object is by definition thread-safe.

In this approach to making an object thread-safe, you don't mark critical sections as synchronized. Instead, you separate out the critical sections that read instance variables from those that write to instance variables. The critical sections that read are left as-is. The critical sections that write must be changed so that, instead of altering the current object's instance variables, they create a new object that embodies the new state and returns a reference to that object.

RGBColor # 3: Thread safety through immutability
Here's an immutable version of RGBColor:

// In file threads/ex3/RGBColor.java
// Instances of this immutable class
// are thread-safe.
public class RGBColor {

    private final int r;
    private final int g;
    private final int b;

    public RGBColor(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 RGBColor invert() {

        RGBColor retVal = new RGBColor(255 - r,
            255 - g, 255 - b);

        return retVal;
    }

    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();
        }
    }
}

Note that the setColor() method is simply removed, as it doesn't make sense in an immutable RGBColor object. The getColor() method, which reads the instance variables, is identical to what it has been, except now it doesn't have to be synchronized. The invert() method, which writes to the instance variables, is changed. Instead of inverting the current object's color, this new invert() creates a new RGBColor object that represents the inverse of the object upon which invert() is invoked, and returns a reference to that object.

<<  Page 6 of 11  >>


Sponsored Links



Google
  Web Artima.com   
Copyright © 1996-2018 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use