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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 朱晓杰 中级黑马   /  2013-4-16 21:56  /  1977 人查看  /  5 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 朱晓杰 于 2013-4-17 17:07 编辑

这些天刚刚跟着毕老师窥探了一下多线程这个神秘的世界,自己动手编写了入学基础测试题的第十题(妈妈做饭的代码),运行结果正常,可是还有一些困惑,下面贴上我的代码:
package com.itheima;

public class Test10 {
        /**
         *第10题:模拟妈妈做饭,做饭时发现没有盐了,让儿子去买盐(假设买盐需要3分钟),只有盐买回来之后,妈妈才能继续做饭的过程。
         *
         * @author zhuxiaojie
         */
          public static void main(String[] args){
                  Salt salt = new Salt();
                  
                  Mother m = new Mother(salt);
                  Son s = new Son(salt);
                  
                  Thread mother = new Thread(m);
                  Thread son = new Thread(s);
                  
                  mother.start();
                  son.start();

                  //mother.setPriority(5);                  //mother.setPriority(1);
          }
}

//共享资源:盐类
class Salt{
        boolean flag = false;
}

//妈妈类
class Mother implements Runnable{
        private Salt salt;
        
        public Mother(Salt salt){
                this.salt = salt;
        }
        
        public void run() {
                while(true){
                        synchronized(salt){
                                if(!salt.flag){
                                        System.out.println("Mother:儿子,没有盐了,你去买盐吧!");
                                        salt.notify();//唤醒儿子去买盐
                                        try {
                                                salt.wait();//等待儿子把盐买回来
                                        } catch (InterruptedException e) {
                                                e.printStackTrace();
                                        }
                                }else{
                                        System.out.println("Mother:做饭中...儿子,待会就能吃饭了!");
                                        System.out.println();
                                        try {
                                                Thread.sleep(1*60*1000);//做饭需要时间
                                        } catch (InterruptedException e) {
                                                e.printStackTrace();
                                        }
                                        salt.flag = false;//改变盐的状态:没盐
                                }
                        }
                }
        }
}

//儿子类
class Son implements Runnable{
        private Salt salt;
        
        public Son(Salt salt){
                this.salt = salt;
        }
        
        public void run() {
                while(true){
                        synchronized(salt){
                                if(!salt.flag){
                                        System.out.println("Son:妈妈,你等会,我现在就去买盐!");
                                        try {
                                                Thread.sleep(3*60*1000);//买盐需要三分钟
                                                salt.flag = true;//改变盐的状态:有盐
                                                System.out.println("Son:妈妈,盐买回来了,什么是否能吃饭啊?");
                                                salt.notify();//唤醒妈妈继续做饭
                                        } catch (InterruptedException e) {
                                                e.printStackTrace();
                                        }
                                }
                                try {
                                        salt.wait();//等待吃饭
                                } catch (InterruptedException e) {
                                        e.printStackTrace();
                                }
                        }
                }
        }
}


困惑一:怎么才能让儿子吃上饭呢?每次儿子买回盐来之后,就又得去买盐!
困惑二:程序运行结果的第一次 总是儿子先去买盐,可是我想让妈妈先执行,后来我想到了设置线程的优先级,但是不管用,请问该怎么处理?线程的优先级什么时候使用?数字越大代表优先级越高?
困惑三:根据题目的需求,我的代码还能怎么优化呢?请各位多多指教!谢谢!

评分

参与人数 1技术分 +2 收起 理由
陈丽莉 + 2 鼓励一下~

查看全部评分

5 个回复

倒序浏览

回帖奖励 +3

本帖最后由 何俊森 于 2013-4-17 15:00 编辑

题目的意思 是模拟做饭的过程。lz的代码运行结果是一直 在买盐,做饭。
  • “困惑一:怎么才能让儿子吃上饭呢?每次儿子买回盐来之后,就又得去买盐!”,----儿子吃上饭,加一条打印语句就可以了。然后结束线程。
  • “困惑二:程序运行结果的第一次 总是儿子先去买盐,可是我想让妈妈先执行,后来我想到了设置线程的优先级,但是不管用,请问该怎么处理?线程的优先级什么时候使用?数字越大代表优先级越高?” -----Java 线程模型涉及可以动态更改的线程优先级。本质上,线程的优先级是从 1 到 10 之间的一个数字,数字越大表明任务越紧急。JVM 标准首先调用优先级较高的线程,然后才调用优先级较低的线程。但是,该标准对具有相同优先级的线程的处理是随机的。如何处理这些线程取决于基层的操作系统策略。在某些情况下,优先级相同的线程分时运行;在另一些情况下,线程将一直运行到结束。请记住,Java 支持 10 个优先级,基层操作系统支持的优先级可能要少得多,这样会造成一些混乱。因此,只能将优先级作为一种很粗略的工具使用。最后的控制可以通过明智地使用 yield() 函数来完成。通常情况下,请不要依靠线程优先级来控制线程的状态。
  • ”困惑三:根据题目的需求,我的代码还能怎么优化呢?请各位多多指教!谢谢!“ 在楼主代码基础上,我是这样改的。
    1. package org.cookingtest;

    2. public class TestCooking {
    3.         /**
    4.          *第10题:模拟妈妈做饭,做饭时发现没有盐了,让儿子去买盐(假设买盐需要3分钟),只有盐买回来之后,妈妈才能继续做饭的过程。
    5.          *
    6.          * @author jugs
    7.          */
    8.         public static void main(String[] args) {
    9.                 Salt salt = new Salt();

    10.                 Mother m = new Mother(salt);

    11.                 Thread mother = new Thread(m);
    12.                 mother.start();

    13.                 // mother.setPriority(5); //mother.setPriority(1);
    14.         }
    15. }

    16. // 共享资源:盐类
    17. class Salt {
    18.         boolean flag = false;
    19. }

    20. // 妈妈类
    21. class Mother implements Runnable {
    22.         private Salt salt;

    23.         public Mother(Salt salt) {
    24.                 this.salt = salt;
    25.         }

    26.         public void run() {
    27.                 while (true) {
    28.                         synchronized (salt) {
    29.                                 if (!salt.flag) {
    30.                                         System.out.println("妈妈开始做饭了。");
    31.                                         System.out.println("Mother:儿子,没有盐了,你去买盐吧!");
    32.                                         Son s = new Son(salt);
    33.                                         Thread son = new Thread(s);
    34.                                         son.start();
    35.                                         try {
    36.                                                 salt.wait();// 等待儿子把盐买回来
    37.                                         } catch (InterruptedException e) {
    38.                                                 e.printStackTrace();
    39.                                         }
    40.                                         System.out.println("Mother:做饭中...儿子,待会就能吃饭了!");
    41.                                 }
    42.                                 System.out.println("妈妈做饭中");
    43.                                 try {
    44.                                         Thread.sleep(1000);// 做饭需要时间
    45.                                 } catch (InterruptedException e) {
    46.                                         e.printStackTrace();
    47.                                 }
    48.                                 System.out.println("Mother:儿子,吃饭了。");
    49.                         }
    50.                         break;
    51.                 }
    52.         }
    53. }

    54. // 儿子类
    55. class Son implements Runnable {
    56.         private Salt salt;

    57.         public Son(Salt salt) {
    58.                 this.salt = salt;
    59.         }

    60.         public void run() {
    61.                 while (true) {
    62.                         synchronized (salt) {
    63.                                 if (!salt.flag) {
    64.                                         System.out.println("Son:妈妈,你等会,我现在就去买盐!");
    65.                                         try {
    66.                                                 Thread.sleep(1000);// 买盐需要三分钟
    67.                                                 salt.flag = true;// 改变盐的状态:有盐
    68.                                                 System.out.println("Son:妈妈,盐买回来了,什么是否能吃饭啊?");
    69.                                                 salt.notify();// 唤醒妈妈继续做饭
    70.                                         } catch (InterruptedException e) {
    71.                                                 e.printStackTrace();
    72.                                         }
    73.                                 }
    74.                         }
    75.                         break;
    76.                 }
    77.         }
    78. }
    复制代码
    以下我我写的。
    1. public class MaiYan02 {
    2.         public static void main(String[] args) {
    3.                 new Thread(new Mother()).start();
    4.         }
    5. }

    6. class Mother implements Runnable {
    7.         public void run() {
    8.                 System.out.println("开始做饭了");
    9.                 System.out.println("妈妈说:\"没盐了,儿子,买盐去!\"");
    10.                 Thread son = new Thread(new Son());
    11.                 son.start();
    12.                 try {
    13.                         son.join();
    14.                 } catch (InterruptedException e) {
    15.                         e.printStackTrace();
    16.                 }
    17.                 System.out.println("盐买回来,妈妈继续做饭。");
    18.         }
    19. }

    20. class Son implements Runnable {
    21.         public void run() {
    22.                 System.out.println("儿子:\"好的,马上去买盐!\"");
    23.                 try {
    24.                         Thread.sleep(3000);
    25.                 } catch (InterruptedException e) {
    26.                         e.printStackTrace();
    27.                 }
    28.         }
    29. }
    复制代码

评分

参与人数 2技术分 +2 黑马币 +2 收起 理由
陈丽莉 + 2
朱晓杰 + 2 很给力!

查看全部评分

回复 使用道具 举报
鼓励一下!!!
回复 使用道具 举报
何俊森 发表于 2013-4-17 11:17
题目的意思 是模拟做饭的过程。lz的代码运行结果是一直 在买盐,做饭。
  • “困惑一:怎么才能让儿子吃上 ...

  • 作者的Salt类并没有什么实际用途啊?
    回复 使用道具 举报
    朱晓杰 发表于 2013-4-17 13:29
    作者的Salt类并没有什么实际用途啊?

    对,那个忘删了。我那个没有想那么复杂,基本适合题目的意思。
    回复 使用道具 举报
    何俊森 发表于 2013-4-17 14:32
    对,那个忘删了。我那个没有想那么复杂,基本适合题目的意思。

    恩恩,是了,我仔细分析了你的代码,挺简单的,只是我现在多线程只学习了一半,线程间的通信还没有完全掌握呢,谢谢你的回答,感觉自己对多线程的理解有加强了!
    回复 使用道具 举报
    您需要登录后才可以回帖 登录 | 加入黑马