CS 102 (Spring 2003)
Quiz 2: Locks

Quiz Posted Given in class
6 Feb 11 Feb
Take-home quiz, turn in on the due date at the start of class. You are free to collaborate in discussing solutions for this problem, but write up your solution by yourself.

Consider the following class which you are not allowed to modify

public class Num {
   private int n;
   public Num(int n)            { setN(n);      }
   public void setN(int n)      { this.n = n;   }
   public int getN()            { return n;     }
}
and suppose we have two instances of Num:
   Num num1 = new Num(0);
   Num num2 = new Num(1);
  1. Why does the following not execute atomically?
      num1.setN(num1.getN() + 1);
    

    Answer: The thread executing the above statement could be interrupted between its fetch of n and its store of n; this is true of any thread even if proper locks are obtained. but with no lock obtained, other threads could execute similar statements causing race conditions at the stores and fetches of n. Thus, the view of the update of n is not atomic.

  2. You cannot change the Num class. Write code to execute the above statement atomically.

    Answer:

        synchronized(num1) {
          num1.setN(num1.getN() + 1);
        }
    

  3. You cannot change the Num class. Write code to swap the contents of num1 and num2 atomically. You must be holding a lock on both objects for this to work.

    Answer:

        synchronized(num1) {
           synchronized(num2) {
              int tmp = num1.getN();
              num1.setN(num2.getN());
              num2.setN(tmp);
           }
        }
    

  4. Under what situations is the constructor shown below race-free?
      public class GenID {
         private static int nextID = 0;
         private        int myID;
         public GenID() {
            myID = nextID;
            nextID = nextID + 1;
         }
         public void getID() { return myID; }
      }
    

    Answer: When no constructor calls for GenID() can execute concurently. That would not be true if multiple, unsynchronized threads could instantiate GenID objects concurrently.

  5. Show how to modify the constructor so that it is always race-free. Note that you cannot put the "synchronized" attribute on a constructor.

    Answer:

      public class GenID {
         private static Object lock = new new Object(); // just for locking
         private static int nextID = 0;
         private        int myID;
         public GenID() {
            myID = nextID;
            synchronized (lock) {
                nextID = nextID + 1;
            }
         }
         public void getID() { return myID; }
      }
    


Last modified 09:58:17 CST 17 February 2003 by Ron K. Cytron