Synchronize access to mutable fields

In a multi-threaded environment, accessing mutable data (data that can change) must always be coordinated between readers and writers. The task of making sure that readers and writers don't interfere with each other in undesirable ways is called synchronization. Synchronization can be done with an explicit lock object, but a more common style is to use the intrinsic locks implied by the synchronized keyword.

For example, in a multi-threaded environment, all get and set methods for mutable fields should usually be synchronized methods. This includes primitive fields.

Most classes do not need to be designed for operation in a multi-threaded environment, and can ignore these considerations.

If an object does need to live in a multi-threaded environment, however, then a significant amount of care must be taken to ensure that it is correctly designed.

If an object is immutable, then it's automatically thread-safe. If it's mutable, then extra steps must be taken to ensure thread-safety: every use of every mutable field must be synchronized in some way (usually with using the synchronized keyword).

Here, mutable field simply means a field which might change in any way, after the initial construction of the object. (Objects are never shared between threads until after the object is fully created.) For example,

Remember that all local variables declared in the body of a method are never shared between threads, and so have no thread-safety considerations.

It's a misconception that all mutable primitives except long and double do not need synchronized access.

Example

Note that even the get of the int field is a synchronized method.


import java.util.Date;

/**
* This class is mutable, but thread-safe : the caller never
* needs to perform external synchronization, except when multiple calls
* need to be treated as a single unit.
*
* This class illustrates the three possible cases for fields :
*<ul>
* <li> a primitive (int)
* <li> an immutable object (String)
* <li> a mutable object (Date)
*</ul>
*/
public final class MutablePlanet {

  public MutablePlanet(int aId, String aName, Date aDateOfDiscovery) {
     fId = aId;
     fName = aName;
     //Make a private copy of aDateOfDiscovery.
     //This is the only way to keep the fDateOfDiscovery
     //field private, and shields this class from any changes
     //to the original aDateOfDiscovery object which might be
     //made by the caller.
     fDateOfDiscovery = new Date(aDateOfDiscovery.getTime());
  }

  public synchronized int getId() {
     return fId;
  }
  public synchronized void setId(int aNewId) {
    fId = aNewId;
  }

  public synchronized String getName() {
    return fName;
  }
  public synchronized void setName(String aNewName) {
    fName = aNewName;
  }

  /**
  * Returns a defensive copy of the field.
  * The caller of this method can do anything they want with the
  * returned Date object, without affecting the internals of this
  * class in any way.
  */
  public synchronized Date getDateOfDiscovery() {
    return new Date(fDateOfDiscovery.getTime());
  }
  public synchronized void setDateOfDiscovery(Date aNewDiscoveryDate) {
    //change the state of the mutable Date field
    fDateOfDiscovery.setTime(aNewDiscoveryDate.getTime());
  }

  // PRIVATE

  /**
  * A primitive field.
  */
  private int fId;

  /**
  * An immutable object field.
  * Strings never alter state after construction.
  */
  private String fName;

  /**
  * A mutable object field.
  * The state of a Date can change after construction.
  */
  private Date fDateOfDiscovery;
}
 



See Also :
Immutable objects
Remember the types of intrinsic lock
Document thread safety
Would you use this technique?
Yes   No   Undecided   
© 2014 Hirondelle Systems | Source Code | Contact | License | RSS
Individual code snippets can be used under this BSD license - Last updated on September 21, 2013.
Over 2,000,000 unique IPs last year - Built with WEB4J.
- In Memoriam : Bill Dirani -