notify 和 notifyall 的区别,yield 和 wait,sleep的区别
2015-12-11 10:18
477 查看
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()的线程有可能在进入到可执行状态后马上又被执行。
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()的线程有可能在进入到可执行状态后马上又被执行。
相关文章推荐
- 使用行为树(Behavior Tree)实现游戏AI
- R包的安装错误ERROR: dependency ‘plyr’ is not available for package ‘reshape2’
- 行为树(Behavior Tree)实践(2)– 进一步的讨论
- VirtualBox is complaining that the kernel module is not loaded
- 行为树(Behavior Tree)实践(1)– 基本概念
- test again
- 人工智能--机器学习相关文章收集
- 【Beta】Daily Scrum Meeting第五次
- 【Beta】Daily Scrum Meeting第五次
- Horizon/DomainWorkFlow
- 15 Which tasks are run automatically as part of the Automated Maintenance Task by default? (Choose a
- LeetCode 220 Contains Duplicate III
- SetWaitableTimer定时器的使用
- HDU 1983 Kaitou Kid - The Phantom Thief (2)(DFS套BFS)
- 线程间通信
- Daily Scrum 12.10
- cf 605A Sorting Railway Cars 贪心 简单题
- 00017: Data frame has at least one annotation group that is enabled and contains graphics
- kaldi monophone training outline
- CodeForces 377C/378E Captains Mode 状态压缩动态规划