java object notify_java Object.wait notify等待通知机制的理解

在java多线程中可以使用object.wait/notify来进行线程之间的通讯 wait会使当前线程进入等待状态,notify会从等待线程中随机解除其等待状态

注意:

使用wait 必须进行try catch

记住调用wait或者notify方法必须采用当前锁调用,即必须采用synchronized中的对象,wait的本意是暂时释放掉对象锁,让别的需要此对象的代码能够有机会执行。

举个例子

当线程B访问某个共享资源时,想获取资源的锁对象,发现这个锁已经被线程A拿到了,这个时候,线程B只能被挂起,等待线程A释放锁。

但是拿到锁的线程A在执行的过程中,因为某些条件还不满足,暂时不想继续执行下去,想先等待一下(注意:是已经拿到锁的线程A自己想主动等待的),希望等到某个条件满足后,继续执行任务。在同步代码块里,线程A必须先释放锁,线程B才有资格获取锁,进入同步代码块,执行代码。等线程B执行完后,线程A需要的条件已经满足,那么这个时候必须有一个通知机制,让线程A从等待状态变成执行状态,继续执行代码。

所以线程之间要协调沟通,必须有一个等待机制和通知机制,在JAVA里面,对应的就是wait方法和notify方法。

Object的wait方法

synchronized (obj) {

while (condition does not ok){

obj.wait();

}

}

如果想让线程A处于等待状态,可以调用当前对象wait方法。wait方法一旦被调用,也就意味着:线程A已经获得锁了,而且能做的事情都已经做了,现在只能等待了,等待另外的同步操作执行某些代码后,我才回来继续干活。

注意:

永远不要在循环之外调用wait方法

对于从wait中被notify的进程来说,它在被notify之后还需要重新检查是否符合执行条件,如果不符合,就必须再次被wait,如果符合才能往下执行。所以:wait方法应该使用循环模式来调用。按照上面的生产者和消费者问题来说:错误情况一:如果有两个生产者A和B,一个消费者C。当存储空间满了之后,生产者A和B都被wait,进入等待唤醒队列。当消费者C取走了一个数据后,如果调用了notifyAll(),注意,此处是调用notifyAll(),则生产者线程A和B都将被唤醒,如果此时A和B中的wait不在while循环中而是在if中,则A和B就不会再次判断是否符合执行条件,都将直接执行wait()之后的程序,那么如果A放入了一个数据至存储空间,则此时存储空间已经满了;但是B还是会继续往存储空间里放数据,错误便产生了。错误情况二:如果有两个生产者A和B,一个消费者C。当存储空间满了之后,生产者A和B都被wait,进入等待唤醒队列。当消费者C取走了一个数据后,如果调用了notify(),则A和B中的一个将被唤醒,假设A被唤醒,则A向存储空间放入了一个数据,至此空间就满了。A执行了notify()之后,如果唤醒了B,那么B不会再次判断是否符合执行条件,将直接执行wait()之后的程序,这样就导致向已经满了数据存储区中再次放入数据。错误产生。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值