美文网首页
java Object.wait notify等待通知机制的理解

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

作者: xiazki | 来源:发表于2017-11-23 14:07 被阅读0次

    在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()之后的程序,这样就导致向已经满了数据存储区中再次放入数据。错误产生。

    相关文章

      网友评论

          本文标题:java Object.wait notify等待通知机制的理解

          本文链接:https://www.haomeiwen.com/subject/vmjzvxtx.html