If you pass a value type, it will be boxed, and the next time the code runs here, it will be boxed again, and it will not be the same object twice, so it cannot be locked
lock(x)
{ ...
}
The lock is actually done through the Monitor object:
The above is equivalent to:
System.Object obj = (System.Object)x; System.Threading.Monitor.Enter(obj); try
{ ...
} finally
{ System.Threading.Monitor.Exit(obj);
}
Then to quote the original words of MSDN: Use Monitor to lockobjects (that is, reference types), not value types. When you pass avalue type variable to Enter, it is boxed as an object. If you pass thesame variable to Enter again, it is boxed as a separate object, and thethread does not block. In this case, the code that Monitor issupposedly protecting is not protected. Furthermore, when you pass thevariable to Exit, still another separate object is created. Because theobject passed to Exit is different from the object passed to Enter,Monitor throws SynchronizationLockException. For more information, seethe conceptual topic Monitors. |