0

I have a question about locking and whether I'm doing it right.

In a class, I have a static lock-object which is used in several methods, assume access modifiers are set appropriately, I won't list them to keep it concise.

class Foo
{ 
   static readonly object MyLock = new object();

   void MethodOne()
   {
       lock(MyLock) { 
          // Dostuff
       }
   }

   void MethodTwo()
   {
       lock(MyLock) { 
          // Dostuff
       }
   }
}

Now, the way I understand it, a lock guarantees only one thread at a time will be able to grab it and get into the DoStuff() part of one method.

But is it possible for the same thread to call MethodOne() and MethodTwo() at the same time? Meaning that he uses the lock he has gotten for both methods?

My intended functionality is that every method in this class can only be called by a single thread while no other method in this class is currently executing.

The underlying usage is a database class for which I only want a single entry and exit point. It uses SQL Compact, so if I attempt to read protected data I get all sorts of memory errors.

Let me just add that every once and a while a memory exception on the database occurs and I don't know where it's coming from. I thought it was because of one thread doing multiple things with the database before completing things, but this code seems to work like it should.

4

4 回答 4

2

但是同一个线程可以同时调用 MethodOne() 和 MethodTwo() 吗?

不,同一个线程不能同时调用这两个方法,无论是否lock使用。

lock(MyLock) 

可以这样理解:

MyLock对象有一个钥匙可以进入自己。首先访问它的线程(比如 t1)得到它。其他线程将不得不等到t1释放它。但是t1可以调用另一个方法并通过这一行,因为它已经获得了锁。

但是,同时调用这两种方法……单线程不可能。不在当前的编程世界中。

按照我的理解,锁保证一次只有一个线程能够抓住它并进入一种方法的 DoStuff() 部分。

您的理解是正确的,但请记住线程用于并行执行,但线程内的执行始终是顺序的。

于 2012-11-15T11:30:48.977 回答
1

但是同一个线程可以同时调用 MethodOne() 和 MethodTwo() 吗?

单个线程不可能同时调用任何东西

在多线程应用程序中,这可能会发生 -方法可以同时调用,但// Dostuff部分只能按顺序访问。

我的预期功能是该类中的每个方法只能由单个线程调用,而该类中当前没有其他方法正在执行。

然后不要在你的应用程序中使用额外的线程——只使用主线程,不要使用额外的线程。

于 2012-11-15T11:30:20.973 回答
1

Dostuff运行MethodOne中的线程调用的唯一方法MethodTwo是调用. 如果这没有发生(即“相互锁定”组中的方法不会相互调用),那么您是安全的。DostuffMethodOneMethodTwo

于 2012-11-15T11:31:04.357 回答
0

There are a few things that can be answered here.

But is it possible for the same thread to call MethodOne() and MethodTwo() at the same time? Meaning that he uses the lock he has gotten for both methods?

No, a thread has a single program counter, its either in MethodOne() or in MethodTwo(). If however you have something as follows,

public void MethodThree()
{
    lock (MyLock)
    {
        MethodOne();
        MethodTwo();
    }
}

That will also work, a thread can acquire the same lock multiple times. Just watch out for what you're doing as you can easily get into a deadlock as the code becomes more complex.

My intended functionality is that every method in this class can only be called by a single thread while no other method in this class is currently executing.

The underlying usage is a database class for which I only want a single entry and exit point. It uses SQL Compact, so if I attempt to read protected data I get all sorts of memory errors.

I don't really understand why, but if you think you need to do this because you're using SqlCompact, you're wrong. You should be using transactions which are supported on SqlCe.

E.g.

using (var connection = new SqlCeConnection())
using (var command = new SqlCeCommand())
using (var transaction = conn.BeginTransaction())
{
    command.Transaction = transaction;
    command.ExecuteNonQuery();
    transaction.Commit();
}
于 2012-11-15T11:43:26.310 回答