关于wait方法的问题

关于wait方法的问题

public synchronized void generate() {

if(flag) {

try {

wait();

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

wait方法 和synchronized 是怎么关联运用的  我在网上搜到说wait是解锁  这里有点懵  求解。。

正在回答

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

5回答

同学你好,这里if(flag)中flag的值是true,因为在if条件中是布尔类型的判断条件时,if(flag)  其实是省略了==true, 其实是 if(flag==true)  可以省略写成if(flag)!所以这里flag代表的是true,与上面定义flag=flase;没有关系哦!

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

  • __Yang 提问者 #1
    好的 非常感谢!
    2019-05-24 12:40:57
提问者 __Yang 2019-05-24 02:09:09

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

boolean flag=false; 创建布尔类型时为什么要等于false, 但教程讲师又说if(flag)里的flag是true,这里不是矛盾了吗? 

  • 提问者 __Yang #1
    如果这里的flag是true的话 那后面的就能理通了,但是创建boolean flag=false;等于false这段不就无意义了吗
    2019-05-24 02:18:32
好帮手慕小班 2019-05-23 15:41:34

同学你好,1、同步是指在执行这个操作的过程中不被打扰,同学的理解没有错!

2、generate()和read()的sleep设置为1000,这里只是将线程的状态从已就绪改变成未准备,当休眠时间(wait/sleep)方法的时间执行完后,线程状态会根据notifyAll();唤醒所有线程,这时线程就会变成已就绪,cpu这时就会从已就绪的状态中来随机选择线程来执行,这时getN和setN都是已就绪状态,要根据flag的判断条件来执行是生产的线程还是消费的线程!所以一定是生产语句先出来,然后根据cpu会执行消费语句,只是程序不复杂,所以运行效率比较快,看不出来!

3、wait是执行等待的方法,在if语句中将线程状态改变,但是还是需要在另一个方法执行完成后,通过notifyAll()来唤醒本线程哦!否则线程会一致等待下去!

4、建议同学在去学习一下课程中的案例哦!这里同学掌握的不是很好哦!

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

  • 提问者 __Yang #1
    多线程可以这样理解吗? wait方法执行会让该线程中断,进而执行第二个线程,第二个线程执行完毕flag值变化,并执行notifyAll方法,使中断的线程继续运行,再改变flag值,notifyAll()...... 当然也可能开始就通过flag不符合if条件,跳过执行wait方法,运行完线程后转而运行第二个线程。
    2019-05-24 02:15:55
  • 好帮手慕小班 回复 提问者 __Yang #2
    这里同学的理解是正确的哦!很棒哦!继续加油~ 祝:学习愉快~
    2019-05-24 10:12:21
提问者 __Yang 2019-05-23 01:10:57

这是我的源代码:

public class Queue {

private int n;

    boolean flag=false;

public synchronized int getN(){

if(!flag) {

try {

wait();

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

flag=false;//消费完毕,容器中没有数据

System.out.println("消费:"+n);

notifyAll();

return n;

}


public synchronized void setN(int n)  {

if(flag) {

try {

wait();

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

System.out.println("生产:"+n);

this.n = n;

flag=true;//生产完毕,容器中已经有数据

notifyAll();

}


}

public class Producer implements Runnable{

    Queue queue;

    Producer(Queue queue){

    this.queue=queue;

    }

@Override

public void run() {

        int i=0;

while(true) {

queue.setN(i++);

try {

Thread.sleep(2000);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}


}

public class Consumer implements Runnable{

    Queue queue;

    Consumer(Queue queue){

    this.queue=queue;

    }

@Override

public void run() {

while(true) {

queue.getN();

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}


}

public class Test {

//运行时,生产和消费 运行先后顺序是随机的

//当运行顺序为先生产后消费时,运行正常

//当运行顺序为先消费后生产时,消费运行后flag

public static void main(String[] args) {

Queue queue=new Queue();

new Thread(new Producer(queue)).start();

        new Thread(new Consumer(queue)).start();

}


}


好帮手慕小班 2019-05-22 10:21:37

同学你好,1、首先wait是解锁的说法是不正确的哦!

2、java中的进程同步是是通过synchronized()来实现的,就是说被synchronized修饰的方法或者代码块中的程序具有一致性,被它修饰后程序不会释放资源!就好像加上锁了!

3、wait()方法,顾名思义就是等待,属于Object类,当调用wait()方法后,也就是让程序执行等待的程序,notify()或者notifyAll()方法后,才会被唤醒,而synchronized()相当于加锁,就好比你进入了一个房间,把门锁上了,在这个线程结束之前,别人是进不来的,也就是说,这个线程执行结束之前,其他线程是没有办法执行这个程序的!

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

  • 提问者 __Yang #1
    很难理解。。同步不是指先执行完该进程才能执行下一个吗? 我的generate()和read()的sleep设置的都是1000, 运行时生产语句,和消费语句 是同时出来的。这里为什么不是先出来生产语句,后出消费语句? 还有wait,和notify的用法 wait通过if(flag)运行后 不是进入了等待状态吗?最后的notifyAll() 它再进行唤醒 这里是什么意义? 我将wait和notifyAll相关语句删除后,程序开始运行时,有时会出现先消费后生产的情况,我知道这原因是缺少那两个方法,但还是不理解这两个方法的作用。希望能够帮我解答。 谢谢!
    2019-05-23 01:09:49
问题已解决,确定采纳
还有疑问,暂不采纳

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

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

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

在线咨询

领取优惠

免费试听

领取大纲

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