Monitor vs WaitHandle
2015-10-14 08:49
453 查看
http://stackoverflow.com/questions/1355398/monitor-vs-waithandle-based-thread-sync
A problem with
For example:
This will always work no matter in which the two statements in the different threads are executed. It's also a very clean abstraction and expresses very clearly your intent.
Now have a look at the same example using a monitor:
Here the signal (
To fix this problem, you need something like this:
This works and is probably even more performant and lightweight, but is less readable. And it's where the headache called concurrency starts.
Does this code really work?
In every corner case?
With more than two threads? (Hint: it doesn't)
How do you unit-test it?
A solid, reliable, readable abstraction is often better than raw performance.
Additionally, WaitHandles provide some nice stuff like waiting for a set of handles to be set, etc. Implementing this with monitors makes the headache even worse...
Rule of thumb:
Use Monitors (
Use WaitHandles (Manual/AutoResetEvent/Semaphore) to send signals between threads
扩展
http://stackoverflow.com/questions/1717194/autoresetevent-manualresetevent-vs-monitor
http://stackoverflow.com/questions/11381771/thread-sleep-vs-monitor-wait-vs-registeredwaithandle
A problem with
Monitor.Pulse/Waitis that the signal may get lost.
For example:
var signal = new ManualResetEvent(false); // Thread 1 signal.WaitOne(); // Thread 2 signal.Set();
This will always work no matter in which the two statements in the different threads are executed. It's also a very clean abstraction and expresses very clearly your intent.
Now have a look at the same example using a monitor:
var signal = new object(); // Thread 1 lock (signal) { Monitor.Wait(signal); } // Thread 2 lock (signal) { Monitor.Pulse(signal); }
Here the signal (
Pulse) will get lost if
Pulseis executed before
Wait.
To fix this problem, you need something like this:
var signal = new object(); var signalSet = false; // Thread 1 lock (signal) { while (!signalSet) { Monitor.Wait(signal); } } // Thread 2 lock (signal) { signalSet = true; Monitor.Pulse(signal); }
This works and is probably even more performant and lightweight, but is less readable. And it's where the headache called concurrency starts.
Does this code really work?
In every corner case?
With more than two threads? (Hint: it doesn't)
How do you unit-test it?
A solid, reliable, readable abstraction is often better than raw performance.
Additionally, WaitHandles provide some nice stuff like waiting for a set of handles to be set, etc. Implementing this with monitors makes the headache even worse...
Rule of thumb:
Use Monitors (
lock) to ensure exclusive access to a shared resource
Use WaitHandles (Manual/AutoResetEvent/Semaphore) to send signals between threads
扩展
http://stackoverflow.com/questions/1717194/autoresetevent-manualresetevent-vs-monitor
http://stackoverflow.com/questions/11381771/thread-sleep-vs-monitor-wait-vs-registeredwaithandle
相关文章推荐
- AIDL通信原理
- LeetCode -- Contains Duplicate
- iredmail下安装脚本分析(一)---get_all.sh 文件所在目录为PKGS
- Windows下Hadoop报错Failed to locate the winutils
- 【LeetCode从零单刷】Container With Most Water
- adb install 报错INSTALL_FAILED_UPDATE_INCOMPATIBLE 解决方法
- hdu4810Wall Painting dp+异或
- rails项目本地运行
- VIVADO报错解决: logical ports have no user assigned specific location constraint (LOC)
- grails2.3.11第一课
- 音乐播放器-MainFragment分析2
- Codeforces Round #325 (Div. 2)D. Phillip and Trains BFS
- 【停课集训10.13】【#3 training】
- Gmail Api 的解读及例子
- hdu 4770 Lights Against Dudely(二进制枚举情况)
- Failed to install Intel HAXM.
- 彻底解决INSTALL_FAILED_UPDATE_INCOMPATIBLE的安装错误
- Exception in thread "main" org.apache.hadoop.security.AccessControlException: Permission denied: use
- Codeforces Round #325 (Div. 2) D. Phillip and Trains
- 正确使用Block避免Cycle Retain和Crash