threads.Lock类 提 供 了 锁 以 保 证 互 斥。
在 临 界 代 码 区 的 两 端 执 行 Lock.acquire()和Lock.release()即可保证同时只有一个线程访问临界代码区,条件变量建立在锁之上,由threads.Condition实现,它是用来保证同步的工具。每一个条件变量拥有一个锁变量 (该锁变量亦可被执行 acquire 和 release 操作, 多个条件变量可共享同一个锁变量)。当处于临界区内的拥有某锁L的当前线程对与锁L联系的条件变量执行sleep操作时,该线程失去锁 L并被挂起。下一个等待锁 L的线程获得锁 L(这个过程由调度程序完成)并进入临界区。当拥有锁 L 的临界区内的当前线程对与锁 L 联系的条件变量执行 wake 操作时 (通常调用wake之后紧接着就是Lock.release),等待在该条件变量上的至多一个被挂起的线程 (由调用sleep引起) 被重新唤醒并设置为就绪状态。若执行wakeall操作,则等待在该条件变量上的所有被挂起的线程都被唤醒。
threads.condition已经实现了一个条件变量 (采用信号量实现),题目要求用屏蔽/禁止中断的方法再实现一下条件变量(写在 threads.condition2中)
1 public class Condition2 { 2 /** 3 * Allocate a new condition variable. 4 * 5 * @param conditionLock 6 * the lock associated with this condition variable. The current 7 * thread must hold this lock whenever it uses <tt>sleep()</tt>, 8 * <tt>wake()</tt>, or <tt>wakeAll()</tt>. 9 */ 10 public Condition2(Lock conditionLock) { 11 this.conditionLock = conditionLock; 12 this.waitedThreads = new LinkedList<KThread>(); 13 } 14 15 /** 16 * Atomically release the associated lock and go to sleep on this condition 17 * variable until another thread wakes it using <tt>wake()</tt>. The current 18 * thread must hold the associated lock. The thread will automatically 19 * reacquire the lock before <tt>sleep()</tt> returns. 20 */ 21 public void sleep() { 22 Lib.assertTrue(conditionLock.isHeldByCurrentThread());//确定当前进程Held the Block 23 boolean intStatus = Machine.interrupt().disable(); 24 waitedThreads.add(KThread.currentThread()); 25 conditionLock.release(); 26 KThread.sleep(); 27 conditionLock.acquire(); 28 Machine.interrupt().restore(intStatus); 29 } 30 31 /** 32 * Wake up at most one thread sleeping on this condition variable. The 33 * current thread must hold the associated lock. 34 */ 35 public void wake() { 36 Lib.assertTrue(conditionLock.isHeldByCurrentThread());//Test if the current thread holds this lock. 37 boolean intStatus = Machine.interrupt().disable(); 38 if (!waitedThreads.isEmpty()) 39 waitedThreads.remove().ready(); 40 Machine.interrupt().restore(intStatus); 41 } 42 43 /** 44 * Wake up all threads sleeping on this condition variable. The current 45 * thread must hold the associated lock. 46 */ 47 public void wakeAll() { 48 Lib.assertTrue(conditionLock.isHeldByCurrentThread()); 49 while (!waitedThreads.isEmpty()) { 50 wake(); 51 } 52 } 53 54 private LinkedList<KThread> waitedThreads; 55 private Lock conditionLock; 56 }