题目要求:模拟妈妈做饭,做饭时发现没有盐了,让儿子去买盐(假设买盐需要3分钟),只有盐买回来之后,妈妈才能继续做饭的过程。然后这是我写的://创建妈妈类
class Mother implements Runnable{
    //设置初始盐量
    static int SaltUsage=0;
    //设置标志
    boolean cooking =true;
    @Override
    public void run() {
        // TODO Auto-generated method stub
        while(cooking){
            if(SaltUsage==0){  //发现盐不够
                Son son=new Son(); //创建son的实例化对象
                son.buySalt(); //用son的实例化对象条用son类内部的方法,较儿子去买盐
                System.out.println("我将等你买盐");
                waitForSon();               
            }
            System.out.println("现在的盐量是 "+SaltUsage+" 足够半个月的饭菜用了");
            System.out.println("继续做饭");
        }
        
    }
    //等待儿子买盐回来
    public synchronized void waitForSon(){
        System.out.println("妈妈等儿子买盐回来");
        try {
            wait();
            System.out.println("妈妈等儿子买盐回来");
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
//创建儿子类
class Son extends Thread{
    //设置标记
    boolean free = true;
    @Override
    public void run(){
        while(free){
            try {
                sleep(180);
                Mother.SaltUsage =100;
                System.out.println("买了 "+Mother.SaltUsage+" 盐回来");
                sonNotify(); //唤醒妈妈   
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            free=false;            
        }
    }
    public synchronized void buySalt(){
        Son son=new Son();
        son.start();
    }
    public synchronized void sonNotify(){
        notify();
    }
}
public class Test10 {
    public static void main(String[] args) {
        Mother mother =new Mother();
        new Thread(mother).start();        
    }
}运行结果是:我将等你买盐
妈妈等儿子买盐回来
买了 100 盐回来
也就是本程序没有运行起来阿,不知道哪里的问题。可能是同步锁的问题javathread

解决方案 »

  1.   

    感觉不是同步锁的问题。
     while(cooking){ 
    你这里的cooking什么时候改成false让程序继续往下运行?
    你应该把母亲的对象传给儿子,儿子调用母亲的方法来修改这个boolean值才对。
      

  2.   


    public class CookingDemo {
    private boolean hasSalt = false;
    private Object syncObj = new Object();

    public CookingDemo() {
    }

    public void cooking() {
    if (!hasSalt) {
    System.out.println("妈妈:儿子,没盐啦,快去买盐");
    new Thread(new SunBuySalt()).start();
    synchronized(syncObj){
    try {
    syncObj.wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    System.out.println("妈妈:有盐了,继续做饭");
    }
    }

    private class SunBuySalt implements Runnable {
    @Override
    public void run() {
    System.out.println("儿子:我出去买盐啦。");
    try {
    System.out.println("儿子:买盐中...等待2秒");
    Thread.sleep(2000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    synchronized(syncObj){
    hasSalt = true;
    System.out.println("儿子:盐买好了。");
    synchronized(syncObj){
    syncObj.notifyAll();
    }
    }
    }

    }

    public static void main(String[] args) {
    CookingDemo demo = new CookingDemo(); 
    demo.cooking();
    }

    /**输出结果:
    妈妈:儿子,没盐啦,快去买盐
    儿子:我出去买盐啦。
    儿子:买盐中...等待2秒
    儿子:盐买好了。
    妈妈:有盐了,继续做饭
     */
    }
      

  3.   


    但是儿子买回盐之后,没能唤醒母亲。这是不是说明,方法用的不对?也不是cooking没有改变boolean值?能不能测试下你的说法,我测试过了,不是这个原因。除非我测试的不对
      

  4.   

    哈哈 这个没这么复杂哈 弄个java回调就解决拉
      

  5.   

    package com.djk.design.huidiao;/**
     * main方法测试
     * @author djk
     *
     */
    public class BuySaltTest
    {
    public static void main(String[] args) 
    {
    Son son = new Son(new Mother());
    son.buySalt();
    }
    }interface DoCook
    {
    /**
     * 做饭
     */
    void cooking(); 
    }class Mother implements DoCook
    { public void cooking()
    {
    System.out.println("盐买回来了,开始做饭吧....");
    }
    }class Son
    {
    private DoCook doCook;

    public Son(DoCook doCook)
    {
    this.doCook = doCook;
    }

    /**
     * 买盐
     */
    public void buySalt()
    {
    try {
    System.out.println("我去买盐拉");
    Thread.sleep(3000);
    //花了3秒买回来了 然后通知妈妈可以做饭了
    doCook.cooking();
    } catch (Exception e) 
    {
    }
    }
    }
      

  6.   

    呵呵 稍微看了下lz的代码 你要唤醒首先要确保你wait和notify是同一把锁
      

  7.   

    你看看这篇日志吧。
    刚才没注意看,认真看完才发现你好像没有真正理解线程同步机制。http://blog.163.com/fan_yishan/blog/static/47692213200881981424126/