0

我是 C# 的初学者。我正在查看多线程示例。

我已经设置了一个多线程的方法调用DoTransactions(),它又会生成一个随机数 as amount,并调用方法来Withdraw()扣除salaryamount

1)我不明白的是为什么作者选择锁定对象thisLock而不是锁定工资?我看到其他一些人也通过声明一个对象并锁定它来以这种方式锁定线程。

2)有时我无法调试其他线程运行时调用的方法。(按 F10/F11)。(例如方法Withdraw())。这有什么原因吗?

Department dep = new Department(1000); 
Thread t = new Thread(new ThreadStart(dep.DoTransactions));   //set up 1000 threads.

class Department
    {
        private Object thisLock = new Object();
        int salary = 10000;

        int Withdraw(int amount)
        {
            lock (thisLock)
            {
                if (salary >= amount)
                {
                    salary = salary - amount;
                    return amount;
                }
            }
        }
4

5 回答 5

2
  1. 您只能锁定类(引用类型),而 Salary 是一个值类型的 int。

MSDN:

lock 语句的表达式必须表示引用类型的值。不会对 lock 语句的表达式执行任何隐式装箱转换(第 6.1.5 节),因此表达式表示值类型的值是编译时错误。

http://msdn.microsoft.com/en-us/library/aa664735(v=vs.71).aspx

  1. 不能调试是什么意思?调试器可能会在线程之间跳转。
于 2013-01-25T16:23:58.650 回答
0

您在lock语句中输入的内容(如lock (thisLock)不是被锁定的数据。如果您考虑一下,情况并非如此:如果您想修改两个变量,您会将哪个变量放入lock?(答案:不存在答案。不可能。)。

取而代之的是,当访问在逻辑上受锁保护的数据时,您将引用始终按惯例锁定的对象。

于 2013-01-25T16:24:41.290 回答
0

在调试多线程应用程序时,使用断点来强制查看特定的代码行。你不能依赖你的步入和跨步依次工作。

于 2013-01-25T16:31:09.687 回答
0

回答你的第二个问题:

可能您需要先选择“全部中断”(单击“全部中断”按钮)停止运行所有线程,然后转到“调试|Windows|线程”查看可以调试的所有线程的列表。(当然,每个都有一个单独的堆栈帧。)

从那里你可以双击一个线程来查看它是否有任何源代码。(有些是您没有启动的“内部”线程,并且这些线程没有您可以看到的源代码。只需继续单击线程,直到找到一个有趣的线程。;)

除此之外,在您感兴趣的线程将执行的代码中设置断点。

于 2013-01-25T16:32:04.630 回答
0

使用锁是为了让只有 1 个线程可以随时访问该位代码。为了启用线程之间的同步,它们必须轮流锁定一个对所有线程都可用的对象。

于 2013-01-25T16:21:56.070 回答