Is it safe to use a boxed value type as a locker for the lock statement?

无人久伴 提交于 2021-02-08 04:58:32

问题


The documentation of the lock statement is pretty straightforward:

lock (x)
{
    // Your code...
}

where x is an expression of a reference type.

So I should not be allowed to pass a value type as locker for a lock. I noticed though that I can use a value type that implements an interface. In other words I can do this:

IDisposable locker = default(DisposableStruct);
lock (locker) Console.WriteLine("Thread safe");

struct DisposableStruct : IDisposable
{
    public void Dispose() { }
}

This was surprising. I figured out that the reason is that the value type is boxed. According to the documentation:

Boxing is the process of converting a value type to the type object, or to any interface type implemented by this value type.

My question is if there are any caveats with using boxed value types as lockers for the lock statement. Is there any possibility for the reference-type wrapper to change somehow during the execution of the program, causing the thread-safe code to fail?


Update: Here is an example of what worries me. Is it guaranteed that if I run the code bellow a million times, the correct output (1,000,000,000) will always be displayed?

IComparable<int> boxedValueType = 0;
int sharedState = 0;
var tasks = Enumerable.Range(0, 10).Select(_ => Task.Run(() =>
{
    for (int i = 0; i < 100_000_000; i++)
        lock (boxedValueType)
            sharedState++;
})).ToArray();
Task.WaitAll(tasks);
Console.WriteLine(sharedState);

来源:https://stackoverflow.com/questions/56864042/is-it-safe-to-use-a-boxed-value-type-as-a-locker-for-the-lock-statement

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!