黑马程序员技术交流社区

标题: 多线程等待问题 [打印本页]

作者: 李大伟    时间: 2012-11-5 23:25
标题: 多线程等待问题
本帖最后由 李大伟 于 2012-11-7 23:14 编辑

模拟妈妈做饭,做饭时发现没有盐了,让儿子去买盐(假设买盐需要3分钟),只有盐买回来之后,妈妈才能继续做饭的过程。

思考 线程问题
* 1 创建两个线程 妈妈线程 和 儿子线程,
* 2 妈妈线程先做饭,儿子线程sleep,后因没有盐 ,妈妈线程sleep 3分钟 ,儿子线程去买盐
* 3 儿子线程买盐回来sleep,妈妈线程做饭
* 但是run方法中 一个做饭,一个买盐不会做 所以……

求各位达人给讲解下 谢谢!!!

谢谢各位
作者: 奋斗的青春    时间: 2012-11-5 23:53
本帖最后由 吴愿涛 于 2012-11-5 23:54 编辑


LZ提到的好像和我之前做的测试题一样哦 。
package com.itheima;

public class Test10 {

        /**
         *  第十题、模拟妈妈做饭,做饭时发现没有盐了,让儿子去买盐(假设买盐需要3分钟),只有盐买回来之后,妈妈才能继续做饭的过程。
         */

            static class Mother extends Thread{
                /** 盐的用量 */
                final int SaltUseage = 40;
                volatile boolean cooking = true;
                Home home;
                public void run(){
                    try {
                        while(cooking){
                            Salt salt = home.salt;
                            if(salt.value<SaltUseage){
                                home.son.buySalt();
                                waiting();
                            }
                            System.out.println("[妈妈]盐  ==>> 当前量:"+salt.value+" 用去量:"+SaltUseage+" 剩余量:"+(salt.value-SaltUseage));
                            salt.value -= SaltUseage;
                            otherThings();
                        }
                    } catch (Exception e) {
                        cooking = false;
                    }
                }
                private void otherThings() {
                    try {
                        sleep(1000);
                    } catch (Exception e) {
                        cooking = false;
                    }
                }
                private synchronized void waiting() throws InterruptedException {
                    System.out.println("[妈妈]盐  ==>> 当前量:"+home.salt.value+"  等待儿子去买盐。");
                    home.mother.wait();
                }
                private synchronized void notice(){
                    home.mother.notify();
                }
            }
            static class Son extends Thread{
                /** 盐的购买量 */
                final int SaltPurchases = 60;
                volatile boolean free = true;
                Home home;
                public void run(){
                    try {
                        while(free){
                            waiting();
                            sleep(2000);
                            System.out.println("[儿子]盐  ==>> 当前量:"+home.salt.value+" 购买量:"+SaltPurchases+" 剩余量:"+(home.salt.value+SaltPurchases));
                            home.salt.value += SaltPurchases;
                            notice();
                        }
                    } catch (Exception e) {
                        free = false;
                    }
                }
                public synchronized void buySalt(){
                    notify();
                }
                private void notice() {
                    System.out.println("[儿子]盐  ==>> 当前量:"+home.salt.value+" 告知妈妈盐已买到。");
                    home.mother.notice();
                }
                private synchronized void waiting() throws InterruptedException {
                    System.out.println("[儿子]盐  ==>> 当前量:"+home.salt.value+" 等待下次购买。");
                    wait();
                }
            }
            static class Salt{
                int value = 90;
            }
            static class Home{
                Mother mother = new Mother();
                Son son = new Son();
                Salt salt = new Salt();
                public Home(){
                    mother.home = this;
                    son.home = this;
                }
                public void startCooking(){
                    mother.start();
                    son.start();
                }
                public void stopCooking(){
                    mother.cooking=false;
                    son.free=false;
                    mother.interrupt();
                    son.interrupt();
                }
            }
            
            /**
             * 测试用例
             */
            public static void main(String[] args) throws Exception {
                Home home = new Home();
                home.startCooking();
                Thread.sleep(15000);
                home.stopCooking();
            }

        }

作者: 罗宝    时间: 2012-11-6 00:01
只需要创建一个妈妈线程就行了,用妈妈实例来调用儿子对象买盐的方法,让妈妈这个线程休眠3分钟后,再用妈妈实例调用儿子对象盐买回来后说话的方法,然后打印妈妈继续做饭,就行了!
作者: 王振    时间: 2012-11-6 00:02
  1. public class ThreadTest {
  2.         public static void main(String[] args) {
  3.                
  4.                 final Object obj = new Object();     //这里创建一个对象,作为锁。
  5.                
  6.                 new Thread(new Runnable() {
  7.                         public void run() {
  8.                                 System.out.println("妈妈开始做饭...");
  9.                                 //这里让该线程停顿3秒钟,模拟正在做饭。
  10.                                 try {
  11.                                         Thread.sleep(3000);
  12.                                 } catch (InterruptedException e) {
  13.                                         e.printStackTrace();
  14.                                 }
  15.                                
  16.                                
  17.                                 System.out.println("妈妈发现没有盐,让儿子去买,等待中...");
  18.                                
  19.                                
  20.                                 synchronized(obj) {
  21.                                         //发现没有盐之后,唤醒另一线程。
  22.                                         obj.notify();
  23.                                        
  24.                                         //当前线程停止。等待唤醒。
  25.                                         try {
  26.                                                 obj.wait();
  27.                                         } catch (InterruptedException e) {
  28.                                                 e.printStackTrace();
  29.                                         }
  30.                                         System.out.println("儿子将盐买回,妈妈继续做饭...");
  31.                                 }
  32.                                
  33.                         }
  34.                 }).start();
  35.                
  36.                 new Thread(new Runnable() {

  37.                         public void run() {
  38.                                 synchronized(obj) {
  39.                                         //该线程一经启动就等待另一线程唤醒。
  40.                                         try {
  41.                                                 obj.wait();
  42.                                         } catch (InterruptedException e) {
  43.                                                 e.printStackTrace();
  44.                                         }
  45.                                        
  46.                                         System.out.println("儿子去买盐...");
  47.                                        
  48.                                         //sleep3秒钟,模拟买盐过程。
  49.                                         try {
  50.                                                 Thread.sleep(3000);
  51.                                         } catch (InterruptedException e) {
  52.                                                 e.printStackTrace();
  53.                                         }
  54.                                        
  55.                                         System.out.println("儿子将盐买回来,线程结束...");
  56.                                         //买完盐后唤醒另一线程。
  57.                                         obj.notify();
  58.                                 }
  59.                         }
  60.                        
  61.                 }).start();

  62.         }

  63. }
复制代码
看看是不是这个意思。
作者: 葛旭东    时间: 2012-11-6 01:42
本帖最后由 葛旭东 于 2012-11-6 01:44 编辑

前面几位仁兄为什么要把这么简单的问题复杂化呢???可以不需要同步函数和同步代码块的啊!!

这是我的代码:
  1. class Mother implements Runnable{
  2.         public  void run(){
  3.                 System.out.println("妈妈在做饭...");
  4.                 System.out.println("发现没有盐了,让儿子去买盐。等待中...");
  5.                 //开启son线程
  6.                 Thread son = new Thread(new Son());
  7.                 son.start();
  8.                 //加入son线程
  9.             try{son.join();}
  10.             catch(InterruptedException e)
  11.             {
  12.                     throw new RuntimeException("妈妈做饭出问题了");
  13.             }
  14.                 System.out.println("可以继续做饭了!!!");
  15.         }
  16. }
  17. class Son implements Runnable{
  18.         public  void run() {
  19.                 System.out.println("儿子出门去买盐了...");
  20.                
  21.                 for(int x=1;x<=3;x++){
  22.                         try{
  23.                                 Thread.sleep(1000);
  24.                         }
  25.                         catch(InterruptedException e)
  26.                         {
  27.                                 throw new RuntimeException("儿子买盐出问题啦!");
  28.                         }
  29.                         System.out.println("过去了"+x+"分钟......");
  30.                 }
  31.                 System.out.println("买盐回来了!");
  32.                
  33.         }
  34. }
  35. public class test10 {
  36.         public static void main(String[] args) {
  37.           //开启Mother线程
  38.       new Thread(new Mother()).start();
  39.         }

  40. }
复制代码





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2