关于synchronized同步锁的问题

关于synchronized同步锁的问题

在本次的自由编程中,对同步锁以及wait方法还是一知半解,导致该题的完成百分之70是照抄同学的做法来完成的; 以下几点是我的疑惑,烦请老师解答一下,太懵了



  1. synchronized该关键字如果修饰方法是不是表示该方法施加了同步锁的方法,方法体中的所有语句块会被同步锁所同步,如果修饰的是类,如:synchronized(this){在该方法体中施加同步锁}(在该大括号语句块外的线程不会受到同步锁的限制而会造成异步情况;

  2. wait方法所代表的是等待,线程阻塞的作用。 用if(flag){};相当于如果值为真时,则实行语句块中的wait方法(),那么如果实行了,它是由什么方式进行唤醒的;   因为在做取反和不取反的判断时,如果操作位置不同会导致线程执行一半或者只执行一条语句就中断了,这点很是不懂。   

  3. 如果用synchronized修饰了方法那么应该没必要在该方法体当中创建synchronized(this){}来限制了吧?

  4. 在做if(flag)的判断时,为啥会出现一条语句都不输出的情况,或者是输出到一半后读取天气信息或者是生成天气信息其中一个语句不输出的只输出读取天气信息或者生成天气信息的情况;代码如下:



正在回答

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

2回答

同学你好,关于同学的问题:

1、同学理解的是正确的。

2、可以使用notify()或者notifyAll()方法唤醒处于等待状态的线程。


​按照同学第一段代码解释一下执行流程:

创建flag对象时,赋值为false,如:

http://img1.sycdn.imooc.com//climg/5f9bc6540983c7da01930037.jpg

顺序执行代码,在generaWeather()方法中,判断if(flag)为false,不执行if中的代码,则向后执行输出生成天气的语句,并设置flag为true。在此之后应该使用notifyAll()唤醒所有线程。



http://img1.sycdn.imooc.com//climg/5f9bc66f09dbaa4206250458.jpg

当再执行generaWeather()方法时,flag为true,执行if中的代码,使该线程处于阻塞状态。


执行readWeather()方法时,上边设置flag为true,!flag为false,不执行if中的代码。执行输出读取天气的语句。在设置flag为false后,应该使用notifyAll()唤醒线程。


http://img1.sycdn.imooc.com//climg/5f9bc70009e5309b05840435.jpg

当flag为false时,!flag为true,执行if中的代码,使线程处于阻塞状态。


综上所述,当flag为flase时,会执行生成天气的代码,而读取天气的线程处于阻塞状态。当flag为ture时,会执行读取天气的代码,而生成天气的线程处于阻塞状态。


另外如果为flag赋初始值为true,则生成天气的方法中应该取反if(!flag),读取天气的方法中为if(flag)。这里应该是先生成天气,再读取天气。


3、是的。

4、当flag为true时,if(flag)会执行if中的代码,使线程处于阻塞状态,不执行输出或生成的代码。

祝:学习愉快~

  • 慕哥8310336 提问者 #1
    对了,老师,我还有一点不解。 在之前的生产消费那个例题,在没有加入notifyAll做线程唤醒时,为啥会出现死锁情况 。 都是有用同步锁进行同步操作了,并也有相应的解锁加锁的方式。
    2020-10-31 11:49:56
  • 慕哥8310336 提问者 #2
    老师,不用解答了,我刚看了其它同学的问题里的老师回答,明白了。
    2020-10-31 12:07:45
  • 好帮手慕阿满 回复 提问者 慕哥8310336 #3
    同学你好,当两个线程都调用wait(),处于等待状态,并且没有notifyAll()唤醒线程,就会出现死锁状态。祝:学习愉快~
    2020-10-31 14:08:52
提问者 慕哥8310336 2020-10-30 12:49:33

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也改变下位置也会不同,这是什么原因。


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

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

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

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

在线咨询

领取优惠

免费试听

领取大纲

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