为什么wait(5000)放在if(flag)前面。就只执行一次啊。

为什么wait(5000)放在if(flag)前面。就只执行一次啊。

public 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){
			try {
				wait();
			} catch (InterruptedException e) {
				// TODO 自动生成的 catch 块
				e.printStackTrace();
			}
		}
		//如果wait(5000)放在最前面。就只等一次。放在后面就是对的。表示不懂为毛。
		try {
			wait(5000);
		} catch (InterruptedException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}
		temperature=(int)(Math.random()*41);
		humidity=(int)(Math.random()*101);
		System.out.println("生成天气数据"+this);
		flag=true;
		notifyAll();
		
	}
	
	public synchronized void read(){
		
		if(!flag){
			try {
				wait();
			} catch (InterruptedException e) {
				// TODO 自动生成的 catch 块
				e.printStackTrace();
			}
		}
		try {
			wait(100);
		} catch (InterruptedException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}
		System.out.println("读取天气数据"+this);
		flag=false;
		notifyAll();
		
		
	}
	@Override
	public String toString() {
		return " [温度:" + temperature + ", 湿度:" + humidity
				+ "]";
	}
	
	
	
	
}
public class GenerateWeather implements Runnable {

	Weather weather;
	
	public GenerateWeather(Weather weather) {
		super();
		this.weather = weather;
	}


	public void run() {
		// TODO 自动生成的方法存根
		for(int i=0;i<100;i++){
			weather.generate();
		}
		
	}

}
public class ReadWeather implements Runnable {

	Weather weather;
	
	
	public ReadWeather(Weather weather) {
		super();
		this.weather = weather;
	}


	public void run() {
		// TODO 自动生成的方法存根
		for(int i=0;i<100;i++){
			
			weather.read();
		}
		
	}

}
public class WeatherTest {

	public static void main(String[] args) {
		// TODO 自动生成的方法存根

		Weather weather=new Weather();
		GenerateWeather generateWeather=new GenerateWeather(weather);
		new Thread(generateWeather).start();
		ReadWeather readWeather=new ReadWeather(weather);
		new Thread(readWeather).start();
	}

}


正在回答 回答被采纳积分+1

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

3回答
irista23 2018-11-25 10:26:46

注意到你的程序只用到了wait方法,而没有使用到sleep(),首先他俩是有区别的:wait方法会让出对象锁,让其他线程执行,而sleep()不会。就是说你程序如果调用到notifyAll()所有wait都会被唤醒,为什么放在前面有等待效果,后面都接着执行了,而放在后面效果上看是正确的,是因为generate()开始的wait()没有被flag值限定,哪个方法调用notifyAll()都会把它唤醒,而放在后面,要等待前面的wait()执行完才能执行它

  • 提问者 蛋定妹 #1
    你的意思是wait执行时,wait(5000)执行后wait()不会执行么
    2018-12-02 08:36:11
好帮手慕雪 2018-11-23 18:11:50

哦,你是说 wait();和wait(5000)并存呀?误解你的意思了。一段代码中不要同时有多个wait()出现,这样会扰乱cpu执行的。notifyAll();也会干扰。你可以使用Thread.sleep(5000);来模拟

  • 提问者 蛋定妹 #1
    很感谢你的积极回复。不过可能是我没表达清楚。。。我的意思是。我现在放上去的程序是对的。可以正常运行的。我在写的过程中出现了一个问题。那就是我把第一个程序中的添加中文解释的代码放到了方法的最前面。就出现了这样的结果:只有最开始的时候等了5秒。后面就一次性出来了结果。我想不清楚这是为什么。然后就有点蒙。。。
    2018-11-23 19:57:44
  • 好帮手慕雪 回复 提问者 蛋定妹 #2
    原因就是一段代码中不要同时有多个wait();,wait(5000)出现,这样会扰乱cpu执行的。notifyAll();也会干扰。所以你的程序后面就被打乱了你的两个wait的本意。wait(5000)改为Thread.sleep(5000);就不会影响了。
    2018-12-02 11:30:21
好帮手慕雪 2018-11-23 17:18:04

如果不加任何判断,两个线程进来直接 wait();谁也执行不到notifyAll();你等我,我等你的,谁也醒不了,就变成死锁了。祝:学习愉快

  • 提问者 蛋定妹 #1
    额。他不是没有结果。他是只等了一次。后面的就直接出来了。而且。我不是wait()。我是wait(5000)。。。
    2018-11-23 17:28:13
问题已解决,确定采纳
还有疑问,暂不采纳

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

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

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

在线咨询

领取优惠

免费试听

领取大纲

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