• JAVA--线程wait()、lnotify()和notifyAll()方法


    join()方法是Thread类的一个方法,而wait()、notify()、notifyAll()是java.lang.Object类的方法,这意味着,任何一个Java对象(包括线程对象)都有wait()、notify()、notifyAll()方法,但只有线程对象才有join()方法。

    wait()方法

    有两种格式:
    格式1:public final void wait() throws InterruptedException
    只有拥有该对象的“对象锁”的线程才能调用该对象的wait()方法。该方法的功能是,使调用者(线程)释放该“对象锁”,并进入“阻塞”状态,Java系统将这个调用者(线程)放入该对象的wait等待队列中。当另外一个线程调用该对象的notify()、notifyAll()方法时,唤醒处于这个对象的wait等待队列中的线程,进入运行态。线程唤醒后能否沿原来断点处继续执行,取决于该线程能否重新得到该对象的“对象锁”。若得不到对象锁,则根据synchronized的获取对象锁的机制,该线程将进入“阻塞”状态,并被放入该对象的对象锁等待队列中。当其他线程归还对象锁时会自动唤醒它。如前所述,另一个线程若调用该线程的interrupt()方法,将唤醒该线程,中断它的“阻塞”状态,进入“运行”态。但只有该线程重新获取到该对象的“对象锁”时,才会抛出InterruptedException异常给该线程。wait()方法使该线程只释放这个对象的对象锁并进入这个对象的wait等待队列中,若该线程同时还拥有其他对象的对象锁,这些对象锁不会被释放。释放对象锁的主要原因是尽可能降低产生线程间死锁的机率。
     
    格式2:public final void wait(long timeout) throws InterruptedException
    其中:timeout是毫秒。
    含义同上。只增加了当指定的时间一到,线程被唤醒,进入运行态。然后线程试图重新获取对象锁。只有获取到对象锁,才能继续原先的断点往下执行。若timeout=0,则等同于wait()。
     
    lnotify()notifyAll()方法
    notify 的格式为:public final void notify()
    只有拥有该对象的“对象锁”的线程才能调用该对象的notify()方法。该方法的功能是,从该对象的wait等待队列中选择一个线程唤醒它,选择的算法由具体实现者决定,可简单认为是从队列中任意选择一个线程。大部分情况下,wait()与notify()或notifyAll()是配套成对使用的。若对一个wait(),程序员忘记用相应的notify()或notifyAll()来唤醒,则极大地增加产生死锁的概率。
    考虑到尽可能降低死锁产生的潜在可能性,通常建议使用notifyAll(),其格式为:public final void notifyAll()
      
    (1) 必须保证,每一个wait()都有相应的notify()或notifyAll()。
    (2) wait()/notify()/notifyAll()是任何一个Java对象都具有的方法,只有拥有该对象的对象锁的线程才能调用wait()/notify()/notifyAll()方法。
    (3) wait()/notify()/notifyAll()方法必须且只能放在synchronized代码块或方法中,且wait()通常放在while()语句中。
    (4) 线程A调用对象K的wait()方法进入对象K的等待队列时,只释放它所拥有的对象的锁,它所拥有的其他对象K的锁并不会释放。
    若一个Java程序的所有线程都因为申请不到它们所需要的资源而全部进入“阻塞”状态时,该Java程序将被挂起,程序再不能继续前进,这种现象称为死锁。
     
  • 相关阅读:
    091115 T UI生成的类
    090717 T OOD时的接口
    090713 T 数组不OO
    090723 T Code Generate 的思考
    091101 T IModel
    091018 CH 培训方法论总结
    090615 T 数据库范式
    写程序,逻辑优先!
    091117 T else if 的写法
    091015 CH 培训所想到的
  • 原文地址:https://www.cnblogs.com/liwenjuan/p/3208703.html
Copyright © 2020-2023  润新知