11.10 练习

11-1 从Runnable继承一个类,并重写run()函数。在run()中打印一个消息,然后调用sleep()。重复这个过程3遍,然后从run()返回。在构造函数中放进一条启动(start-up)消息,并且在任务结束时打印一个关闭(shut-down)消息。创建几个此类型的线程对象,运行它们并观察会发生什么结果。

11-2 修改BasicThreads.cpp,使LiftOff线程启动其他的LiftOff线程。

11-3 修改ResponsiveUI.cpp,消除任何可能的竞争条件。(假设bool操作是非原子的。)

11-4 在Incrementer.cpp中,修改Count类,使用一个int变量而不使用int数组。解释产生的行为。

11-5 在EvenChecker.h中,纠正Generator类中的潜在问题。(假设bool操作是非原子的。)

11-6 修改EvenGenerator.cpp,使用interrupt()而不使用退出标志。

11-7 在MutexEvenGenerator.cpp中,改变MutexEvenGenerator:nextValue()中的代码,使返回表达式处在release()语句之前,并解释会有什么情形发生。

11-8 修改ResponsiveUI.cpp,使用interrupt()而非quitFlag方法。

11-9 查看ZThread库中Singleton的文档。修改OrnamentalGarden.cpp,以便Display对象被一个单件Singleton控制,防止多个Display对象被意外地创建。

11-10 改变OrnamentalGarden.cpp中的Count:increment()函数,使它直接对count增1(即使用count++)。现在删去保护,看看是否会引起失败。这种做法是安全可靠的吗?

11-11 修改OrnamentalGarden.cpp,使用interrupt()而非pause()机制。确保这种解决方案不会过早销毁对象。

11-12 修改WaxOMatic.cpp,添加Process类的更多实例,使它对汽车外壳上蜡进行3次上蜡和抛光,而不是只有一次。

11-13 创建Runnable的两个子类,一个子类在run()中启动然后调用wait()。另一个子类的run()获得第1个Runnable对象的引用。在若干秒后其run()会为第1个线程调用signal(),以使第1个线程可以打印一条消息。

11-14 创建一个“忙等待”的例子。一个线程休眠一段时间,然后把一个标志设置为true。第2个线程在一个while循环中监视这个标志(这就是“忙等待”),当标志变为true时,把它设置回为false,并把这个变化报告给控制台。注意程序在“忙等待”中耗费了多少时间,创建该程序的第2个版本,使用wait()代替“忙等待”。特别提示:运行profiler,显示在每种情况下使用的CPU时间。

11-15 修改TQueue.h,添加可允许的最大元素计数值。如果元素数达到这个数量,后续的写操作应该被阻塞,直到元素计数小于最大元素计数值为止。编写代码检测这种行为。

11-16 修改ToastOMaticMarkII.cpp,使用两条独立的流水线,在烤面包三明治上涂抹花生酱和果酱,并为已完成的三明治使用一个输出队列TQueue。使用一个Reporter对象显示结果,就像在CarBuilder.cpp中那样。

11-17 使用真正的线程处理而非模拟线程处理重写C07:BankTeller.cpp。

11-18 修改CarBuilder.cpp,给机器人添加标识符,并且添加不同种类机器人的更多实例。注意是否所有机器人都得到利用。

11-19 修改CarBuilder.cpp,给汽车制造进程增加另一个阶段,添加排气系统、车身、挡泥板。如同在第1阶段,假设这些进程可同时被机器人执行。

11-20 修改CarBuilder.cpp,使Car可以对所有bool(布尔)变量进行同步访问。因为互斥锁Mutex不能被拷贝,这将需要对整个程序进行重大的修改。

11-21 使用本章给出的CarBuilder.cpp中的方法,给房屋建筑的例程建模。

11-22 创建一个Timer类,这个类有两个选项:一个只发射一次的一次射击计时器,以及每隔一定的时间间隔定期发射的计时器。和C10:MulticastCommand.cpp一起使用这个类,把对TaskRunner:run()的调用从程序中移到计时器类中。

11-23 改变哲学家进餐的例子中的两处内容,以便除了思考时间之外,还在命令行上控制Philosopher的数量。尝试输入不同的值并解释结果。

11-24 改变DiningPhilosophers.cpp,以便Philosopher正确拿起下一根可用的筷子。(当一个Philosopher取完其筷子后,他们把筷子放入一个筷笼中。当Philosopher需要进餐时,他们就从筷笼中取出下两根可用的筷子。)这种做法能够消除死锁的可能性吗?能仅通过减少可用筷子的数量而重新引入死锁吗?