关于synchronized同步锁的问题
在本次的自由编程中,对同步锁以及wait方法还是一知半解,导致该题的完成百分之70是照抄同学的做法来完成的; 以下几点是我的疑惑,烦请老师解答一下,太懵了
synchronized该关键字如果修饰方法是不是表示该方法施加了同步锁的方法,方法体中的所有语句块会被同步锁所同步,如果修饰的是类,如:synchronized(this){在该方法体中施加同步锁}(在该大括号语句块外的线程不会受到同步锁的限制而会造成异步情况;
wait方法所代表的是等待,线程阻塞的作用。 用if(flag){};相当于如果值为真时,则实行语句块中的wait方法(),那么如果实行了,它是由什么方式进行唤醒的; 因为在做取反和不取反的判断时,如果操作位置不同会导致线程执行一半或者只执行一条语句就中断了,这点很是不懂。
如果用synchronized修饰了方法那么应该没必要在该方法体当中创建synchronized(this){}来限制了吧?
在做if(flag)的判断时,为啥会出现一条语句都不输出的情况,或者是输出到一半后读取天气信息或者是生成天气信息其中一个语句不输出的只输出读取天气信息或者生成天气信息的情况;代码如下:
正在回答
同学你好,关于同学的问题:
1、同学理解的是正确的。
2、可以使用notify()或者notifyAll()方法唤醒处于等待状态的线程。
按照同学第一段代码解释一下执行流程:
创建flag对象时,赋值为false,如:
顺序执行代码,在generaWeather()方法中,判断if(flag)为false,不执行if中的代码,则向后执行输出生成天气的语句,并设置flag为true。在此之后应该使用notifyAll()唤醒所有线程。
当再执行generaWeather()方法时,flag为true,执行if中的代码,使该线程处于阻塞状态。
执行readWeather()方法时,上边设置flag为true,!flag为false,不执行if中的代码。执行输出读取天气的语句。在设置flag为false后,应该使用notifyAll()唤醒线程。
当flag为false时,!flag为true,执行if中的代码,使线程处于阻塞状态。
综上所述,当flag为flase时,会执行生成天气的代码,而读取天气的线程处于阻塞状态。当flag为ture时,会执行读取天气的代码,而生成天气的线程处于阻塞状态。
另外如果为flag赋初始值为true,则生成天气的方法中应该取反if(!flag),读取天气的方法中为if(flag)。这里应该是先生成天气,再读取天气。
3、是的。
4、当flag为true时,if(flag)会执行if中的代码,使线程处于阻塞状态,不执行输出或生成的代码。
祝:学习愉快~
package com.imooc.weather;
//天气类
public class Weather {
private int temperature;
private int humidity;
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 generaWeather(){
if(flag){
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
temperature=(int)(Math.random()*40);
humidity=(int)(Math.random()*100);
System.out.println("生成天气信息:"+toString());
flag=true;
}
@Override
public String toString() {
return "温度:"+this.temperature+",湿度:"+this.humidity;
}
public synchronized void readWeather() {
if(!flag){
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("读取天气信息:"+toString());
flag=false;
}
}
//代码1;
package com.imooc.weather;
//天气类
public class Weather {
private int temperature;
private int humidity;
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 generaWeather(){
if(flag){
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
temperature=(int)(Math.random()*40);
humidity=(int)(Math.random()*100);
System.out.println("生成天气信息:"+toString());
flag=false;
}
@Override
public String toString() {
return "温度:"+this.temperature+",湿度:"+this.humidity;
}
public synchronized void readWeather() {
if(!flag){
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("读取天气信息:"+toString());
flag=true;
}
}
//如果将取反位置改变一下结果就会不同,如果将低部的flag=true也改变下位置也会不同,这是什么原因。
- 参与学习 人
- 提交作业 7317 份
- 解答问题 14452 个
想要入门学编程?多年一直活跃在编程语言排行版前列的Java是一个很好的选择。本路径将从Java基础语法、面向对象、常用工具类三部分,为你开启软件开发的大门!
了解课程
恭喜解决一个难题,获得1积分~
来为老师/同学的回答评分吧
0 星