CSE 132 (Spring 2009)
Studio 4: Multiple Locks and Dining Philosophers
(Locks and Lox)

Review studio procedures, if necessary, before starting.

Some guidelines for this week's studio:


Setup

You should use eclipse 3.4 for this, not eclipse 3.2.
  1. Open eclipse and your CSE132 project, or create a new Java project CSE132, asking it to keep source and object files in the same folder (ask a student for help if you need it).
  2. Download and import this zip into your project.

Get Acquainted (15 minutes)

  1. Make sure the runAll() method in Main is calling .run() on the new Threads, so that no concurrency is happening yet.
  2. Spend a few minutes changing the colors that get shown when a Phil gets hungry.
  3. Add another state for a Phil object so that it doesn't just study but plays after studying. Pick a suitable color to show when the Phil is playing in PhilViz.
    Be sure to use status("playing") so that its change in state is observed via the PropertyChangeSupport.
    After announcing its status as playing, have the Phil pause in act() for a second (1000 ms) while playing.
  4. If you can, arrange for the Phil randomly to play or study (but not do both) after it has eaten.
  5. OK time for deadlock: change the call to .run() in runAll() to .start().
  6. Run the program a few times and explain what you see.

Double Locks

The Phil object, when it acts, has to get two locks, one on each Chop. Based on what you learned in class today, you will develop a DoubleLock object that first models the behavior we saw in class and then avoids deadlock.

  1. The DoubleLock class implements LockInvokable.
  2. The constructor for DoubleLock takes in two LockInvokableSingleObject objects, say o1 and o2:
    public DoubleLock(LockInvokableSingleObject o1, LockInvokableSingleObject o2) {
    }
    
  3. The lockInvoke(Runnable) method is as follows:
    /**
      * While holding both locks, run r
      */
    public void lockInvoke(final Runnable r) {
       lock1.lockInvoke(
          new Runnable() {
             public void run() {
                Actor.sleep(5);  // will cause deadlock to show its hideous face
                lock2.lockInvoke(r);
             }
          }
       );
    }
    
  4. Open Phil in the editor.
  5. In the constructor, instantiate a DoubleLock object based on the existing LockPubs l1 and l2.
  6. Change act so that after being hungry, it uses the DoubleLock's lockInvoke method to run the code:
       status("eating");
       sleep(300);
    
  7. You should continue to see deadlock.
  8. Now fix DoubleLock so that deadlock is impossible, using Havender's algorithm as discussed in class.
  9. Show a TA your code and run the progam to show it works without deadlock.

Multiple Locks (Puzzler)

If you are short on time, think about this one outside of Studio.

If two locks are good, then an arbitarary number might be better.

  1. Look at the class MultipleLock that will implement LockInvokable, as follows.
  2. The constructor accepts an array of Objects.
  3. The lockInvoke method obtains a lock on all of the objects in the array, and then runs the Runnable.
    • Don't worry about deadlock yet, just be sure you hold all the locks.
    • Remember you can use helper methods if needed.
  4. Try out the MultLockTest as a JUnit test and make sure it passes.
  5. Modify MultipleLock so that it accepts an array of LockInvokableSingleObjects? The lockInvoke method would make sure a lock was held for each getObject() of the LockInvokableSingleObjects before running r.
    Be careful -- you want to use the LockInvokableSingleObject to get a lock on its contained object, but you want the ordering to be based on the object itself.
  6. OK, now worry about deadlock: how do you make sure that use of your MultipleLock class never results in deadlock?


Last modified 20:11:01 CST 11 January 2010 by Ron K. Cytron