Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/webpack/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么对单独的对象执行锁定?_C#_.net_Locking_Thread Safety - Fatal编程技术网

C# 为什么对单独的对象执行锁定?

C# 为什么对单独的对象执行锁定?,c#,.net,locking,thread-safety,C#,.net,Locking,Thread Safety,可能重复: 在我看到的所有“线程安全”代码示例中,它们锁定在一个单独的虚拟对象上。为什么不能直接对相关数据执行锁定?锁定一个单独的私有虚拟对象可以保证没有其他人锁定该对象 如果您锁定了数据,并且同一段数据对外可见,那么您将失去这种保证。例如: public class MyObject { public void SharedMethod() { lock (this) { // Do stuff }

可能重复:


在我看到的所有“线程安全”代码示例中,它们锁定在一个单独的虚拟对象上。为什么不能直接对相关数据执行锁定?

锁定一个单独的
私有
虚拟对象可以保证没有其他人锁定该对象

如果您锁定了数据,并且同一段数据对外可见,那么您将失去这种保证。例如:

public class MyObject
{
    public void SharedMethod()
    {
        lock (this)
        {
            // Do stuff
        }
    }
}

class Program
{
    static void Main(string[] args)
    {
        MyObject o = new MyObject();

        lock (o)
        {
            new Thread(() =>
            {
                // Gets blocked 2s because of external lock
                o.SharedMethod();
            }).Start();

            Thread.Sleep(2000);
        }
    }
}

Eric Gunnerson的博客上有一些很棒的东西。请参阅和。

Jeff Richter(CLR Via C#的作者)在本文中解释了原因

具体来说,在那篇文章中,“为什么伟大的想法不是那么伟大”一节回答了你的问题

这实际上是书中的一章


总之,将私有对象作为“synclock”对象允许类封装和控制类所需的任何锁定。因此,无论有多少客户机使用您的类,锁定都会始终正确地执行。

+1。我本想指出他的书,但这篇文章实际上是一样的!如果某个对象在某些操作期间需要锁定,并且如果外部代码可能需要执行两个或多个操作而不释放它们之间的锁,则该对象必须公开锁或获取并释放锁的方法。暴露两者都不会使外部代码无法正确地完成它需要做的事情。好问题,这也是我的第一个想法。为了帮助人们最好地找到他们正在寻找的答案,这个问题不应该被关闭@比尔,所谓的完全重复问题的标题和措词都很笨拙,没有明确说明与这一问题不同的基本问题。我相信这个问题更有可能在搜索中引起注意。如果我投票决定重新开放,我想我明白了。如果你有一个单独的虚拟对象,那么通过锁定一个你想使用的对象,你并没有阻止它做任何事情?我的意思是,当你试图调用该对象上需要时钟的方法时。是的,锁定私有虚拟对象的主要优点是,您知道只有您的代码会锁定这些对象,这样外部代码就不会影响内部同步机制。