我正试图锁定我对多线程的理解。我正在尽最大努力自学,但其中一些问题需要澄清。
我已经对一段代码进行了三次迭代,尝试使用锁定。
在这段代码中,唯一需要锁定的是this.managerThreadPriority。
首先,简单的程序化方法,带有简约的锁定。
var managerThread = new Thread
(
new ThreadStart(this.ManagerThreadEntryPoint)
);
lock (this.locker)
{
managerThread.Priority = this.managerThreadPriority;
}
managerThread.Name = string.Format("Manager Thread ({0})", managerThread.GetHashCode());
managerThread.Start();
接下来,创建和启动新线程的单个语句,但锁的范围似乎太大,无法包括线程的创建和启动。编译器不会神奇地知道在使用 this.managerThreadPriority 后可以释放锁。
我认为应该避免这种幼稚的锁定。
lock (this.locker)
{
new Thread
(
new ThreadStart(this.ManagerThreadEntryPoint)
)
{
Priority = this.managerThreadPriority,
Name = string.Format("Manager Thread ({0})", GetHashCode())
}
.Start();
}
最后,创建和启动新线程的单个语句,仅在共享字段周围使用“嵌入式”锁。
new Thread
(
new ThreadStart(this.ManagerThreadEntryPoint)
)
{
Priority = new Func<ThreadPriorty>(() =>
{
lock (this.locker)
{
return this.managerThreadPriority;
}
})(),
Name = string.Format("Manager Thread ({0})", GetHashCode())
}
.Start();
想要评论锁定语句的作用域吗?例如,如果我需要在 if 语句中使用一个字段并且该字段需要锁定,我是否应该避免锁定整个 if 语句?例如
bool isDumb;
lock (this.locker) isDumb = this.FieldAccessibleByMultipleThreads;
if (isDumb) ...
对比
lock (this.locker)
{
if (this.FieldAccessibleByMultipleThreads) ...
}
请您参考如下方法:
1) 在启动另一个线程之前,您根本不必担心共享访问它。
2) 是的,您应该锁定对共享可变数据的所有 访问。 (如果它是不可变的,则不需要锁定。)
3) 不要使用 GetHashCode() 来指示线程 ID。使用 Thread.ManagedThreadId。我知道,有些书推荐 Thread.GetHashCode() - 但请查看文档。
