Chapter 2: Protect Your Shared Mutable Collection

Protect Your Collections

/** not thread-safe */
class Crew {

  private final List<String> members = new ArrayList<>();

  void add(String name) {
    if (!members.contains(name)) {
      members.add(name);
    }
  }

  int size(){
    return this.members.size();
  }
}
  • unprotected shared memory
  • documented
  • collection field is final (but doesn't help here)
  • read collection and then change collection state based on the read result
/** thread-safe */
class Crew {

  /** guarded by 'members' */
  private final List<String> members = new ArrayList<>();

  void add(String name) {
    synchronized (this.members) {
      if (!this.members.contains(name)) {
        this.members.add(name);
      }
    }
  }

  int size() {
    synchronized (this.members) {
      return this.members.size();
    }
  }
}
  • now thread-safe
  • synchronized critical section with private lock object (link to other comparisons)
  • the 'standard' way of protecting any shared state
  • be aware: critical section encompasses both read and write, as it's atomic