notify 和 notifyall 的区别,yield 和 wait,sleep的区别

来源:互联网 发布:淘宝浏览单佣金3 3 3 编辑:程序博客网 时间:2024/06/03 19:57

notify 和 notifyall 的区别

void notify(): 唤醒一个正在等待该对象的线程。
void notifyAll(): 唤醒所有正在等待该对象的线程。

具体到问题呢 场景呢? 
有一种场景, 当目前有锁的线程call了 obj.notify(), 接着obj.wait() 了。 而被当前线程 notify的线程 在获得锁对象后,又立刻执行了 wait()方法,则此时则所有线程都进了 obj waitting queue。 没有线程去抢锁, 造成死锁现象之一  (另一种常见的死锁 A拿了A锁且需要B锁,同时B拥有B锁且需要A锁,卡死)

而使用notifyall()则只要有其他线程会去 抢锁,就不会死锁。

场景eg refer to http://sumory.com/2014/03/18/java-thread/


当然在可以awake 一个线程的情况下,唤醒所有线程去acquire 也是一种浪费

following is  from stackoverflow:

Simply put, it depends on why your threads are waiting to be notified. Do you want to tell one of the waiting threads that something happened, or do you want to tell all of them at the same time?

In some cases, all waiting threads can take useful action once the wait finishes. An example would be a set of threads waiting for a certain task to finish; once the task has finished, all waiting threads can continue with their business. In such a case you would use notifyAll() to wake up all waiting threads at the same time.

Another case, for example mutually exclusive locking, only one of the waiting threads can do something useful after being notified (in this case acquire the lock). In such a case, you would rather usenotify(). Properly implemented, youcould use notifyAll() in this situation as well, but you would unnecessarily wake threads that can't do anything anyway.


yield 和 wait的区别

首先wait是 object方法,且和notify*一样 必须获得锁才能使用,所以必须在sync块里。 invoking wait会释放锁,将自己放到 obj的waitting queue上,然后等待下次obj monitor去notify自己,从而进入runnable状态去 compete monitor lock


yield是Thread 方法可以不在sync里,暂时让出 cpu时间片,让自己从running 变成runnable ,结论:yield()从未导致线程转到等待/睡眠/阻塞状态。在大多数情况下,yield()将导致线程从运行状态转到可运行状态,但有可能没有效果。


sleep和yield都属于 Thread方法,不需要在sync里,sleep()使当前线程进入停滞(BLOCKED 注:等带object的lock和 sleep都是blocked状态,在waitting queue中是waitting状态or time_waitting状态 )状态,所以执行sleep()的线程在指定的时间内肯定不会执行;yield()只是使当前线程重新回到可执行状态,所以执行yield()的线程有可能在进入到可执行状态后马上又被执行。



0 0