我有一个关于锁定的问题以及我是否正确行事。
在一个类中,我有一个静态锁对象,它在几个方法中使用,假设访问修饰符设置得恰当,我不会列出它们以保持简洁。
class Foo
{
static readonly object MyLock = new object();
void MethodOne()
{
lock(MyLock) {
// Dostuff
}
}
void MethodTwo()
{
lock(MyLock) {
// Dostuff
}
}
}
现在,按照我理解的方式,锁定一次只保证一个线程能够获取它并进入一个方法的DoStuff()部分。
但同一个线程是否可以同时调用MethodOne()和MethodTwo()?这意味着他使用了他为这两种方法获得的锁?
我的预期功能是此类中的每个方法只能由单个线程调用,而此类中没有其他方法当前正在执行。
基础用法是一个数据库类,我只想要一个入口和出口点。它使用SQL Compact,因此如果我尝试读取受保护的数据,我会收到各种各样的内存错误。
让我简单地说,数据库中每隔一段时间发生一次内存异常,我不知道它来自哪里。我认为这是因为一个线程在完成任务之前对数据库做了很多事情,但是这段代码看起来应该像它应该的那样。
答案 0 :(得分:2)
但同一个线程是否可以同时调用MethodOne()和MethodTwo()?
没有。相同的线程不能同时调用这两个方法,无论是否使用lock
。
lock(MyLock)
可以理解如下:
MyLock
对象有一个键进入自己。一个访问它的线程(比如t1)首先得到它。其他线程必须等到t1
释放它。但t1
可以调用另一个方法,并且会传递此行,因为它已经获得锁定。
但是,同时调用两种方法......单线程不可能。不在当前的编程世界中。
我理解它的方式,一个锁只保证一次只有一个线程能够抓住它并进入一个方法的DoStuff()部分。
您的理解是正确的,但请记住,线程用于执行并行执行,但线程内的执行始终是顺序的。
答案 1 :(得分:1)
但同一个线程是否可以同时调用MethodOne()和MethodTwo()?
单个线程无法同时调用任何。
在多线程应用程序中,可能会发生这种情况 - 可以同时调用方法,但// Dostuff
部分只能按顺序访问。
我的预期功能是此类中的每个方法只能由单个线程调用,而此类中没有其他方法当前正在执行。
然后不要在你的应用程序中使用额外的线程 - 只需使用主线程,不要使用额外的线程。
答案 2 :(得分:1)
正在运行Dostuff
的{{1}}内线程调用MethodOne
的唯一方法是MethodTwo
的{{1}}拨打电话Dostuff
。如果没有发生这种情况(即“互锁”组中的方法不相互呼叫),那么您就是安全的。
答案 3 :(得分:0)
这里可以回答一些问题。
但同一个线程是否可以调用MethodOne()和 MethodTwo()同时?意思是他使用了他拥有的锁 得到这两种方法?
不,一个线程有一个程序计数器,它位于MethodOne()
或MethodTwo()
。但是,如果您有以下内容,
public void MethodThree()
{
lock (MyLock)
{
MethodOne();
MethodTwo();
}
}
那也行,一个线程可以多次获得相同的锁。请注意你正在做的事情,因为随着代码变得更加复杂,你很容易陷入僵局。
我的预期功能是此类中的每个方法都只能 由单个线程调用,而此类中没有其他方法 目前正在执行。
基础用法是我只想要的数据库类 单一进入和退出点。它使用SQL Compact,所以如果我尝试 读取受保护的数据我得到各种各样的内存错误。
我真的不明白为什么,但是如果你认为你需要这样做是因为你使用的是SqlCompact,那你就错了。您应该使用transactions在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();
}