Documentation
The Java™ Tutorials
Download Ebooks
Download JDK
Search Java Tutorials
Hide TOC
Concurrency
Processes and Threads
Thread Objects
Defining and Starting a Thread
Pausing Execution with Sleep
Interrupts
Joins
The SimpleThreads Example
Synchronization
Thread Interference
Memory Consistency Errors
Synchronized Methods
Intrinsic Locks and Synchronization
Atomic Access
Liveness
Deadlock
Starvation and Livelock
Guarded Blocks
Immutable Objects
A Synchronized Class Example
A Strategy for Defining Immutable Objects
High Level Concurrency Objects
Lock Objects
Executors
Executor Interfaces
Thread Pools
Fork/Join
Concurrent Collections
Atomic Variables
Concurrent Random Numbers
For Further Reading
Questions and Exercises
Trail: Essential Classes
Lesson: Concurrency
Section: Immutable Objects
« Previous • Trail • Next »

# A Synchronized Class Example

The class, ``SynchronizedRGB``, defines objects that represent colors. Each object represents the color as three integers that stand for primary color values and a string that gives the name of the color.

    public class SynchronizedRGB {

        // Values must be between 0 and 255.
        private int red;
        private int green;
        private int blue;
        private String name;

        private void check(int red,
                           int green,
                           int blue) {
            if (red < 0 || red > 255
                || green < 0 || green > 255
                || blue < 0 || blue > 255) {
                throw new IllegalArgumentException();
            }
        }

        public SynchronizedRGB(int red,
                               int green,
                               int blue,
                               String name) {
            check(red, green, blue);
            this.red = red;
            this.green = green;
            this.blue = blue;
            this.name = name;
        }

        public void set(int red,
                        int green,
                        int blue,
                        String name) {
            check(red, green, blue);
            synchronized (this) {
                this.red = red;
                this.green = green;
                this.blue = blue;
                this.name = name;
            }
        }

        public synchronized int getRGB() {
            return ((red << 16) | (green << 8) | blue);
        }

        public synchronized String getName() {
            return name;
        }

        public synchronized void invert() {
            red = 255 - red;
            green = 255 - green;
            blue = 255 - blue;
            name = "Inverse of " + name;
        }
    }

`SynchronizedRGB` must be used carefully to avoid being seen in an inconsistent state. Suppose, for example, a thread executes the following code:

    SynchronizedRGB color =
        new SynchronizedRGB(0, 0, 0, "Pitch Black");
    ...
    int myColorInt = color.getRGB();      //Statement 1
    String myColorName = color.getName(); //Statement 2

If another thread invokes `color.set` after Statement 1 but before Statement 2, the value of `myColorInt` won't match the value of `myColorName`. To avoid this outcome, the two statements must be bound together:

    synchronized (color) {
        int myColorInt = color.getRGB();
        String myColorName = color.getName();
    }

This kind of inconsistency is only possible for mutable objects — it will not be an issue for the immutable version of `SynchronizedRGB`.

« Previous • Trail • Next »

Previous page: Immutable Objects
Next page: A Strategy for Defining Immutable Objects