黑马程序员技术交流社区
标题:
求教妈妈做饭,小明买盐 这样写代码可以吗
[打印本页]
作者:
wangliujieok
时间:
2013-4-7 13:04
标题:
求教妈妈做饭,小明买盐 这样写代码可以吗
模拟妈妈做饭,做饭时发现没有盐了,让儿子去买盐(假设买盐需要3分钟),只有盐买回来之后,妈妈才能继续做饭的过程。
@author Administrator
请教:这样写代码符合题目要求吗? 请大师给予指点
class Mather implements Runnable
{
//private static boolean ture;
private boolean b = false;
public void run()
{
if(b)
{
System.out.println("有盐了.....");
System.out.println("妈妈做饭.....");
return;
}
if(!b)
{
System.out.println("没有盐了....");
System.out.println("妈妈暂停做饭....");
try
{
Thread.sleep(1800);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.println("妈妈让儿子去买盐....");
}
Son.run();
}
}
class Son//implements Runnable
{
public static void run()
{
System.out.println("儿子去买盐.....");
System.out.println("盐买回来了.....");
System.out.println("儿子叫妈妈继续做饭.....");
}
}
class MakeDinner
{
public static void main(String[] args)
{
Mather mother = new Mather();
Thread t1 = new Thread(mother);
t1.start();
}
}
作者:
冯超
时间:
2013-4-7 13:06
看看······!!!!!!!!!!!!!!!!
作者:
张洪慊
时间:
2013-4-7 14:43
本帖最后由 张洪慊 于 2013-4-7 16:25 编辑
个人感觉利用等待唤醒机制更好点:
下面仅供参考(每个人思路不同,能实现就行,复习下线程0.0)
/*
需求:
模拟妈妈做饭,做饭时发现没有盐了,
让儿子去买盐(假设买盐需要3分钟),
只有盐买回来之后,妈妈才能继续做饭的过程。
分析:(可以利用等待唤醒机制)
共享资源:盐
两个线程:妈妈 和 儿子
这里的 妈妈 和 儿子 分别相当于
消费者 生产者 模型
思想:
①把盐,妈妈和儿子都单独封装为一个类,分别描述
②由于妈妈和儿子中有线程要运行的代码,
因此使妈妈和儿子实现Runnable接口,复写run方法
③利用等待唤醒机制即
当妈妈发现没盐了(wait),唤醒(notify)儿子去买盐
当儿子买回来盐,唤醒妈妈去做饭
*/
//盐类
class Salt{
private boolean flag=false;//设置一个共享标记
public Salt(){}
public boolean getFlag(){//获取当前标记值
return flag;
}
public boolean changeFlag(boolean flag){//对外提供一个改变标记的方法
return this.flag=flag;
}
}
//妈妈类
class Mom implements Runnable{
private Salt s;//在内部使用盐对象
public Mom(Salt s){
this.s=s;
}
public void run(){ //使用同步函数,因为下面要用到wait,notify,指明锁
while(true){
synchronized(s){
if(!s.getFlag()){//由于只有一个线程执行该run方法,采用if判断
System.out.println("①妈妈说:没盐了,儿子买盐去吧,妈妈等着你");
s.notify();//唤醒同一个锁上的儿子
try{s.wait(3*60*1000);
}
catch(Exception e){
e.printStackTrace();
}
}
System.out.println("③好儿子,盐买回来了,妈妈接着给你做饭");
s.changeFlag(false);//以上做完饭,买的盐用完.
}
}
}
}
//儿子类
class Son implements Runnable{
private Salt s;
public Son(Salt s){
this.s=s;
}
public void run(){
while(true){
synchronized(s){
if(!s.getFlag()){//没盐->儿子去买
System.out.println("②好的妈妈,你等一会哈,我这就去");
s.changeFlag(true);//如果再次执行,儿子不在买盐
s.notify();//已有盐 唤醒妈妈做饭
try{s.wait();
}
catch(Exception e){
e.printStackTrace();
}
}
}
}
}
}
class BuySaltTest{
public static void main(String[] args){
Salt s=new Salt();
//分别创建两个线程执行指定接口子类对象run方法
new Thread(new Mom(s)).start();
new Thread(new Son(s)).start();
}
}
复制代码
作者:
随便
时间:
2013-4-7 15:53
本帖最后由 邓宫财 于 2013-4-7 15:55 编辑
public class SaltTest {
public static void main(String[] args) {
//定义做饭的对象
final Cook c = new Cook();
//定义一个妈妈做饭的线程,并启动
new Thread(new Runnable() {
public void run() {
while(true){
c.makeCook();
}
}
}).start();
//定义一个儿子买盐的线程,并启动
new Thread(new Runnable() {
public void run() {
while(true){
c.buySalt();
}
}
}).start();
}
}
/**
* 因为妈妈儿子需要用到相同的锁对象,和相同的是否能做饭的标示对戏那个,所以把他们封装在一个类中的两个方法中。
* @author Dgc
*/
class Cook{
//是否能做饭的标识
private boolean canCook = false;
/**
* 妈妈做饭的方法
*/
public synchronized void makeCook(){
//如果没有盐,就等待3分钟,唤醒儿子去买盐。
if(!canCook){
System.out.println("没有盐,不能做饭...");
System.out.println("等待买盐....");
try {
this.notify();
Thread.sleep(1000 * 3 * 60);
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//能做饭了。做完之后,把变量设置回去。
System.out.println("妈妈正在做饭。。。");
canCook = false;
}
/**
* 儿子买盐的方法
*/
public synchronized void buySalt(){
//如果能做饭,儿子就休息
if(canCook){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//如果没有盐,儿子去买盐并唤醒妈妈,把能做饭设置true
System.out.println("儿子去买盐了,");
canCook = true;
this.notify();
}
}
复制代码
作者:
wangliujieok
时间:
2013-4-7 16:30
邓宫财 发表于 2013-4-7 15:53
多谢各位大师,代码及思路看明白了 线程我才学了一半:lol
作者:
随便
时间:
2013-4-7 16:39
wangliujieok 发表于 2013-4-7 16:30
多谢各位大师,代码及思路看明白了 线程我才学了一半
加油。共同学习,共同进步。
作者:
Bule_Silence
时间:
2013-7-13 12:05
我觉得本题考查的不是多线程通信问题,大家把问题想复杂了,仅仅考查的就是java基础。
/*
需求:
模拟妈妈做饭,做饭时发现没有盐了,
让儿子去买盐(假设买盐需要3分钟),
只有盐买回来之后,妈妈才能继续做饭的过程。
分析:(可以利用等待唤醒机制)
共享资源:盐
两个线程:妈妈 和 儿子
这里的 妈妈 和 儿子 分别相当于
消费者 生产者 模型
思想:
①把盐,妈妈和儿子都单独封装为一个类,分别描述
②由于妈妈和儿子中有线程要运行的代码,
因此使妈妈和儿子实现Runnable接口,复写run方法
③利用等待唤醒机制即
当妈妈发现没盐了(wait),唤醒(notify)儿子去买盐
当儿子买回来盐,唤醒妈妈去做饭
*/
//盐类
class Salt{
private boolean flag=false;//设置一个共享标记
public Salt(){}
public boolean getFlag(){//获取当前标记值
return flag;
}
public boolean changeFlag(boolean flag){//对外提供一个改变标记的方法
return this.flag=flag;
}
}
//妈妈类
class Mom implements Runnable{
private Salt s;//在内部使用盐对象
public Mom(Salt s){
this.s=s;
}
public void run(){ //使用同步函数,因为下面要用到wait,notify,指明锁
while(true){
synchronized(s){
if(!s.getFlag()){//由于只有一个线程执行该run方法,采用if判断
System.out.println("①妈妈说:没盐了,儿子买盐去吧,妈妈等着你");
s.notify();//唤醒同一个锁上的儿子
try{s.wait(3*60*1000);
}
catch(Exception e){
e.printStackTrace();
}
}
System.out.println("③好儿子,盐买回来了,妈妈接着给你做饭");
s.changeFlag(false);//以上做完饭,买的盐用完.
}
}
}
}
//儿子类
class Son implements Runnable{
private Salt s;
public Son(Salt s){
this.s=s;
}
public void run(){
while(true){
synchronized(s){
if(!s.getFlag()){//没盐->儿子去买
System.out.println("②好的妈妈,你等一会哈,我这就去");
s.changeFlag(true);//如果再次执行,儿子不在买盐
s.notify();//已有盐 唤醒妈妈做饭
try{s.wait();
}
catch(Exception e){
e.printStackTrace();
}
}
}
}
}
}
class BuySaltTest{
public static void main(String[] args){
Salt s=new Salt();
//分别创建两个线程执行指定接口子类对象run方法
new Thread(new Mom(s)).start();
new Thread(new Son(s)).start();
}
}
复制代码
会无限循环下去,很明显题意就是简单地让做饭停止3分钟,然后继续执行,根本就不需要多线程通信来完成。
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2