当前位置:  开发笔记 > 编程语言 > 正文

C#threading - 锁定对象

如何解决《C#threading-锁定对象》经验,为你挑选了2个好方法。

我试图在ac#app中锁定一个"盒装"对象,这不可能吗?

    class t
    {
        System.Object t_x = new object();

        public t(int p)
        {
            t_x = p;

        }

        public void w()
        {
            lock (t_x)
            {
                for (int i = 0; i < 4; i++)
                {

                    {
                        t_x = ((int)t_x) + 1;
                        Console.WriteLine(t_x);
                        Thread.Sleep(1000);
                    }
                }
            }
        }
    }

在另一个类中,我可以开始2个线程:

        Thread b1 = new Thread(new ThreadStart(t1.w));
        b1.Start();
        Thread b2 = new Thread(new ThreadStart(t1.w));
        b2.Start();

但是该部分未锁定.当我锁定一个任意对象(即一个已创建但未被修改为对象a = new object())时,它会很好地锁定.拳击操作不知何故"depromotes"我的对象?



1> Lee..:

不,你不能这样做 - 锁定块是以下的简写:

try(Monitor.Enter(lockObject))
{
    //critical section
}
finally
{
    Monitor.Exit(lockObject)
}

Monitor.Enter的文档指出,"使用Monitor来锁定对象(即引用类型),而不是值类型.当您将值类型变量传递给Enter时,它将被装箱为对象.如果您将相同的变量传递给再次输入,它被装箱为一个单独的对象,并且该线程不会阻止"


这是正确的答案 - 不是因为代码片段(`lock`语句很好),而是因为它提到了值和引用类型之间的区别.每次将值类型转换为通用`object`基类时,它都会再次装箱,因此它无法可靠地充当锁定目标.所以这比接受的答案要好.

2> AgileJon..:

您需要创建一个单独的锁定对象.问题是你在循环中重新分配t_x.假设线程b1在b2到达lock语句之前进入循环,则b2将被允许在lock语句中,因为到那时,t_x将是一个没有锁定的新对象.


@Cedric - 更仔细地阅读Lee的回答.`lock`语句与使用`Monitor.Enter`和`Monitor.Exit`完全相同.它只是同一模式的更简洁的语法.问题不在于是否使用`lock`或`Monitor`(不是真正的选择,因为它们是相同的).问题是始终传递相同的对象作为锁,如果您使用值类型,则会被破坏,因为在您访问它时它会以不同的方式装箱.
推荐阅读
我我檬檬我我186
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有