麻烦老师看一下代码哪里逻辑错误了,就是想不出来

麻烦老师看一下代码哪里逻辑错误了,就是想不出来

class Weather {
    private int temperature;//温度
    private int humidity;//湿度
    private boolean flag=false;//表示该实例内是否有新数据生成
    public int getTemperature() {
        return temperature;
    }
    public void setTemperature(int temperature) {
        this.temperature = temperature;
    }
    public int getHumidity() {
        return humidity;
    }
    public void setHumidity(int humidity) {
        this.humidity = humidity;
    }
    public synchronized void generate() {
        if(!flag) {
            this.setTemperature((int)(Math.random()*40));
            this.setHumidity((int)(Math.random()*100));
            flag=true;
            System.out.println("生产天气数据:"+this.toString());
        }else {
            try {    
                wait();
                notifyAll();
            } catch (InterruptedException e) {
                // TODO 自动生成的 catch 块
                e.printStackTrace();
            }
        }
    }
    public synchronized void read() {
        if(flag) {
            System.out.println("读取天气数据:"+this.toString());
            flag=false;
        }else {
            try {
                wait();
                notifyAll();
            }catch(InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    public String toString() {
        return "[温度:"+this.getTemperature()+",湿度:"+this.getHumidity()+"]";
    }
}

//--------------------------------------------------------------------------------

public class WeatherTest {//测试类
    public static void main(String[]args) {
        Weather w=new Weather();
        Thread t1=new Thread(new GenerateWeather(w));
        Thread t2=new Thread(new ReadWeather(w));
        t1.start();
        t2.start();
    }
}

//------------------------------------------------------------------------------------

class GenerateWeather implements Runnable{//生成天气
    private Weather w;
    public GenerateWeather(Weather w) {
        this.w=w;
    }
    @Override
    public void run() {
        // TODO 自动生成的方法存根
        while(true) {
            w.generate();
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO 自动生成的 catch 块
                e.printStackTrace();
            }
        }
    }

}

//-------------------------------------------------------------------------------

class ReadWeather implements Runnable{//读取天气
    private Weather w;
    public ReadWeather(Weather w) {
        this.w=w;
    }
    public void run() {
        while(true) {
            w.read();
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                // TODO 自动生成的 catch 块
                e.printStackTrace();
            }
        }
    }
}

//-----------------------------------

以下是运行结果:(程序还在运行,但没有新的输出产生)

生产天气数据:[温度:21,湿度:81]
读取天气数据:[温度:21,湿度:81]
生产天气数据:[温度:22,湿度:60]

正在回答

登陆购买课程后可参与讨论,去登陆

2回答

同学你好,以Weather类中生产天气数据方法为例,当flag判断不符合条件时,应该wait等待。在被唤醒后要执行生产天气数据代码。所以,不能使用if else语句,应该使用if语句。
如下:
http://img1.sycdn.imooc.com//climg/5eb13b5a09d0325005370518.jpg

如果我的回答解决了你的疑惑,请采纳!祝学习愉快!

  • notFoundMoneyE 提问者 #1
    老师说的我不是很明白,但我个人的理解是两个线程中wait()的位置都在notifyaAll()的前面,因此可能导致两个线程都处于wait状态(因为唤醒方法在wait的后面)所以造成了问题中的输出情况
    2020-05-05 21:59:41
好帮手慕阿慧 2020-05-06 11:03:48

同学你好,
1、同学代码的执行情况有可能如下:最初flag为false时,生产方法生产天气数据,修改flag为true。这时读取方法由于条件不成立,处于等待状态。由于生产完数据后没有notifyAll,所以读取方法一直在等待。生产方法再次运行时,由于!flag条件不成立,所以执行wait()方法。这时生产和读取方法都处于wait状态。
2、wait()的位置应该notifyAll()前面,notifyAll方法应该放在生产或读取代码的后面。
方法中代码逻辑如下:在if条件不成立时,调用wait方法,进入等待,被唤醒后方法继续执行,生产或读取数据。在if条件成立时,直接生产或读取数据。

如果我的回答解决了你的疑惑,请采纳!祝学习愉快!

问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星
请稍等 ...
意见反馈 帮助中心 APP下载
官方微信

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师