import java.util.*; /** On construction, saves away two {@link LockInvokable} objects * On demand, via lockInvoke on this object, lock those two objects and run the supplied code */ public class DoubleLock implements LockInvokable { private LockInvokable o1, o2; private static Random rand = new Random(); /** Save the {@link LockInvokable} objects in a random order. Leave * this constructor alone! */ public DoubleLock(LockInvokable o1, LockInvokable o2) { setLockOrder(o1, o2); } // Leave this method alone! private void setLockOrder(LockInvokable o1, LockInvokable o2) { if (rand.nextBoolean()) { this.o1 = o1; this.o2 = o2; } else { this.o1 = o2; this.o2 = o1; } } /** Obtain both locks (using lockInvoke) and then call the {@link Runnable} */ public void lockInvoke(final Runnable r) { // FILL IN } /** Return a {@link String} that indocates the order in which the locks are obtained */ public String toString() { return "Lock " + o1 + " and then " + o2; } }