5-3作业运行之后只有读取天气数据,而且数据为0

5-3作业运行之后只有读取天气数据,而且数据为0

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
public class Weather {
     
    private int temperature,humidity;
    boolean flag=true;
     
    public Weather(){
         
    }
    public int getTemperature() {
        return temperature;
    }
    public void setTemperature(int a) {
        this.temperature = a;
    }
    public int getHumidity() {
        return humidity;
    }
    public void setHumidity(int b) {
        this.humidity = b;
    }
     public synchronized void generate(){
         while(flag){
             try {
                 wait();
             catch (InterruptedException e) {
                 // TODO Auto-generated catch block
                 e.printStackTrace();
             }
         }
           
         this.setTemperature((int)(Math.random()*40));
         this.setHumidity((int)(Math.random()*100));
         System.out.println("生成天气数据[温度:"+this.getTemperature()+",湿度:"+this.getHumidity()+"]");
         flag=true;
         notifyAll();
 }
     public synchronized void read(){
         while(!flag){
             try {
                 wait();
             catch (InterruptedException e) {
                 // TODO Auto-generated catch block
                 e.printStackTrace();
             }
         }
         System.out.println("读取天气数据[温度:"+this.getTemperature()+",湿度:"+this.getHumidity()+"]");
         flag=false;
         notifyAll();
 }
 
    @Override
    public String toString() {
        return "天气数据 [温度=" + temperature + ", 湿度=" + humidity + "]";
    }
     
}
public class GenerateWeather implements Runnable {
    Weather weather;
 
    public GenerateWeather(Weather weather) {
        this.weather = weather;
    }
 
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            weather.generate();
            System.out.println("生成"+ weather);
            try {
                Thread.sleep(5000);
            catch (InterruptedException e) {
                // TODO 自动生成的 catch 块
                e.printStackTrace();
            }
        }
    }
}
public class ReadWeather implements Runnable {
    Weather weather;
 
    public ReadWeather(Weather weather) {
        this.weather = weather;
    }
 
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            weather.read();
            try {
                Thread.sleep(500);
            catch (InterruptedException e) {
                // TODO 自动生成的 catch 块
                e.printStackTrace();
            }
        }
    }
}
public class WeatherTest {
    public static void main(String[] args) {
        new Thread(new GenerateWeather(new Weather())).start();
        new Thread(new ReadWeather(new Weather())).start();
 
    }
}
运行之后只有读取天气数据,而且数据为0,这一章实在是听不太明白了,求老师耐心指导,谢谢。


正在回答

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

3回答

你好,问题如下:

1、Weather类的generate和read方法不应该用while,而是if,即if(flag)和if(!flag),如果flag为true或false后调用wait()方法,如果是循环就会一直循环下去,因为循环中flag的值没有变化,所以一直满足条件,程序就会一直执行。

2、为什么会输出一次数据0呢,因为flag初始值为true,满足generate方法中的条件,所以一开始生成数据的方法在等待,并且没有数据生成。而读取数据的方法没有等待,可以执行输出语句,因为温度和湿度都没有赋值,所以输出的是默认值0。然后flag的值变为false,read()方法再次执行时也会调用wait()方法进行等待,所以也就没有任何输出了。

3、GenerateWeather类中,run()方法中不要写输出语句,因为该方法并没有用synchronize关键字修饰,所以代码可能在执行一半的时候被打断,就会使输出结果不符合作业要求。

4、WeatherTest类,两个线程共享一个Weather类对象,所以是先创建一个Weather类的对象weather,GenerateWeather类和ReadWeather类创建对象时的参数都是weather

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

  • 半岛鸡盒 提问者 #1
    非常感谢!
    2017-05-26 18:50:27
慕田峪4427088 2017-06-10 09:34:15

请教一下老师,在两个同步方法输出包含相关天气信息的语句之后将flag重新设置为true和false有什么作用? 

提问者 半岛鸡盒 2017-05-26 18:49:25

太谢谢了!

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

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

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

0 星
请稍等 ...
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号

在线咨询

领取优惠

免费试听

领取大纲

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