A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 李慧声 于 2013-4-8 10:18 编辑
  1. <div class="blockcode"><blockquote>package com.itheima;

  2. /**
  3. * 第10题: 模拟妈妈做饭,做饭时发现没有盐了,
  4. * 让儿子去买盐(假设买盐需要3分钟),只有盐买回来之后,妈妈才能继续做饭的过程。
  5. * @author Lihsh
  6. *
  7. */
  8. public class Test10 {
  9.         /**
  10.          * 测试类实现主方法,用来测试程序
  11.          * @param args
  12.          */
  13.         public static void main(String[] args) {
  14.                 new Thread(new MotherCooking("Mom" , false)).start(); //mum做饭
  15.         }
  16. }
  17. /**
  18. * 思路:Mum在做饭,发现没盐了,调动儿子的线程,去买盐;
  19. * 此时,调用son的join()方法,让mum的线程在儿子的线程执行结束之后再执行。
  20. * @author Lihsh
  21. *
  22. */
  23. class MotherCooking implements Runnable{
  24.         private boolean hasSalt;
  25.         private String name;
  26.         public MotherCooking(String name , boolean hasSalt) {
  27.                 this.name = name;
  28.                 this.hasSalt = hasSalt;
  29.         }
  30.         @Override
  31.         public void run() {
  32.                 System.out.println("Mother is cooking...");
  33.                 while(!hasSalt) { //no salt is true
  34.                         System.out.println("Jim , come here and help mum to buy some salt... ");
  35.                         //调用son,让son去买盐
  36.                         try {
  37.                                 Thread t1 = new Thread(new SonBuySalt("Jim",false));
  38.                                 t1.start();
  39.                                 t1.join();
  40.                         } catch (InterruptedException e) {
  41.                                 e.printStackTrace();
  42.                         }
  43.                         hasSalt = true;
  44.                 }
  45.                 if(hasSalt){ //买的盐的话,那就接着做饭,(能成循环中跳出来,那自然就是买到盐了 hasSalt is true)
  46.                         System.out.println("Thanks ,I will continue to cook...");
  47.                 }
  48.         }
  49. }

  50. /**
  51. * 描述:son买盐的功能类,当Mum调用时启动。
  52. * 通过标志位isBuyed(是否买的盐)来控制线程的执行。
  53. * @author Lihsh
  54. *
  55. */
  56. class SonBuySalt implements Runnable {
  57.         private String name;
  58.         private boolean isBuyed;//买到盐与否
  59.         
  60.         public SonBuySalt(){}
  61.         public SonBuySalt(String name , boolean isBuyed)
  62.         {
  63.                 this.name = name;
  64.                 this.isBuyed = isBuyed;
  65.         }
  66.         @Override
  67.         public void run() {
  68.                 System.out.println("OK , Mum!"); //去买盐了
  69.                 while(!isBuyed){
  70.                         try {
  71.                                 Thread.sleep(3 * 60 * 1000);
  72.                         } catch (InterruptedException e) {
  73.                                 e.printStackTrace();
  74.                         }
  75.                         isBuyed = true;
  76.                 }               
  77.                 if(isBuyed){
  78.                         System.out.println("Mum , I have bought salt...");
  79.                 }
  80.         }        
  81. }
复制代码
运行结果:
Mother is cooking...
Jim , come here and help mum to buy some salt...
OK , Mum!
Mum , I have bought salt...
Thanks ,I will continue to cook...

好像逻辑就应该是这样的吧,我是不敢确定,求同志门指点!
更新了一下代码。

评分

参与人数 1技术分 +1 收起 理由
黄玉昆 + 1

查看全部评分

11 个回复

倒序浏览
可以呀,加点注释,要不看起来费劲
还有答题要注意啊三点
1.把思路写上去
2.注释要详细
3.运行要正常
回复 使用道具 举报
我手心里的宝 发表于 2013-4-7 11:03
可以呀,加点注释,要不看起来费劲
还有答题要注意啊三点
1.把思路写上去

嗯,谢谢,我稍微修改了一下代码,我是在想这里面需不需要同步synchronized呢?不知道,比较纠结。。。
回复 使用道具 举报
这个就可以理解为消费者与生产者的例子
需要同步,不建议使用join方法
思路:设计两个线程
线程一:妈妈做饭
线程二:儿子买烟
过程三分钟可以用wait();来实现
里面加上时间就可以了 我的建议哈 使用同步

评分

参与人数 1技术分 +1 收起 理由
黄玉昆 + 1

查看全部评分

回复 使用道具 举报
我手心里的宝 发表于 2013-4-7 12:55
这个就可以理解为消费者与生产者的例子
需要同步,不建议使用join方法
思路:设计两个线程

这个为什么需要同步?可能我对这个思路不是很理解.能否详细解释下,因为我觉得,如果没有盐,那做饭的线程应该是暂停的,然后执行买盐的线程,不冲突啊!
回复 使用道具 举报
许兵兵 发表于 2013-4-7 17:20
这个为什么需要同步?可能我对这个思路不是很理解.能否详细解释下,因为我觉得,如果没有盐,那做饭的线程应 ...

我也是这样想的,比较困惑。
回复 使用道具 举报
我手心里的宝 发表于 2013-4-7 12:55
这个就可以理解为消费者与生产者的例子
需要同步,不建议使用join方法
思路:设计两个线程

求解释为啥需要同步?
回复 使用道具 举报
我同意上面的用2个线程来实现,做饭没盐了去买盐,继续做饭,又没盐了又去买盐。这就跟生产者消费者一样。下面用同步写的
  1. public class BuySalt {

  2.         /**
  3.          * @param args
  4.          */
  5.         public static void main(String[] args) {
  6.                 // TODO Auto-generated method stub
  7.                 Salt salt = new Salt();
  8.                 Mun mun = new Mun(salt);
  9.                 Son son = new Son(salt);
  10.                 new Thread(mun).start();
  11.                 new Thread(son).start();
  12.         }

  13. }
  14. class Salt
  15. {
  16.         private boolean hassalt=true;
  17.         public void saltUse()
  18.         {
  19.                 System.out.println("正在使用盐");
  20.         }
  21.         public void saltBuy()
  22.         {
  23.                 System.out.println("正在买盐");
  24.         }
  25.         public void setSalt(Boolean hassalt)
  26.         {
  27.                 this.hassalt=hassalt;
  28.         }
  29.         public boolean getSalt()
  30.         {
  31.                 return hassalt;
  32.         }
  33. }
  34. class Mun implements Runnable
  35. {
  36.         private Salt salt;
  37.         Mun(Salt salt)
  38.         {
  39.                 this.salt=salt;
  40.         }
  41.         public void run()
  42.         {
  43.                 while(true)
  44.                 {
  45.                         synchronized(salt)
  46.                         {
  47.                                 if(!salt.getSalt())
  48.                                         try {
  49.                                                 salt.wait();
  50.                                         } catch (InterruptedException e) {
  51.                                                 // TODO Auto-generated catch block
  52.                                                 e.printStackTrace();
  53.                                         }
  54.                                 System.out.println("有盐了,妈妈做饭");
  55.                                 salt.saltUse();                       
  56.                                 try {
  57.                                         Thread.sleep(5000);
  58.                                 } catch (InterruptedException e) {
  59.                                         // TODO Auto-generated catch block
  60.                                         e.printStackTrace();
  61.                                 }
  62.                                 salt.setSalt(false);
  63.                                 System.out.println("儿子,盐用光了,去买盐");
  64.                                 salt.notify();                       
  65.                         }
  66.                 }
  67.         }
  68.        
  69. }
  70. class Son implements Runnable
  71. {
  72.         private Salt salt;
  73.         Son(Salt salt)
  74.         {
  75.                 this.salt=salt;
  76.         }
  77.         public void run()
  78.         {
  79.                 while(true)
  80.                 {
  81.                         synchronized(salt)
  82.                         {
  83.                                 if(salt.getSalt())
  84.                                         try {
  85.                                                 salt.wait();
  86.                                         } catch (InterruptedException e) {
  87.                                                 // TODO Auto-generated catch block
  88.                                                 e.printStackTrace();
  89.                                         }
  90.                                 System.out.println("好的,妈妈,我这就买盐去");
  91.                                 try {
  92.                                         Thread.sleep(5000);
  93.                                 } catch (InterruptedException e) {
  94.                                         // TODO Auto-generated catch block
  95.                                         e.printStackTrace();
  96.                                 }
  97.                                 salt.saltBuy();
  98.                                 System.out.println("妈妈,盐买回来了,你做饭吧");
  99.                                 salt.setSalt(true);
  100.                                 salt.notify();
  101.                         }
  102.                 }       
  103.         }
  104. }
复制代码

点评

最好把代码加上一些适当的注释,这样看着更清晰些  发表于 2013-4-7 19:39
回复 使用道具 举报
如果问题未解决,请继续追问,如果没有问题了,请将帖子分类 改为“已解决”,谢谢
回复 使用道具 举报
我觉得这个可以理解成两个 单线程的 生产者 消费者,妈妈做饭没有盐,唤醒儿子线程去买盐,妈妈等待,儿子买盐回来,唤醒妈妈线程做饭,儿子等待.
回复 使用道具 举报
HM朱俊 发表于 2013-4-7 19:29
我同意上面的用2个线程来实现,做饭没盐了去买盐,继续做饭,又没盐了又去买盐。这就跟生产者消费者一样。 ...

谢谢啊,明白了,应该就是生产者消费者模型,我的做法太局限了。
回复 使用道具 举报
李大伟 发表于 2013-4-7 21:31
我觉得这个可以理解成两个 单线程的 生产者 消费者,妈妈做饭没有盐,唤醒儿子线程去买盐,妈妈等待,儿子 ...

嗯,明白了。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马