我不会说英语,并且使用翻译。
我想知道何时研究线程同步。
class MainApp
{
static public int count = 0;
static private object tLock = new object();
static void plus()
{
for (int i = 0; i < 100; i++)
{
lock (tLock)
{
count++;
Console.WriteLine("plus " + count);
Thread.Sleep(1);
}
}
}
static void minus()
{
for (int i = 0; i < 100; i++)
{
lock (tLock)
{
count--;
Console.WriteLine("minus " + count);
Thread.Sleep(1);
}
}
}
static void Main()
{
Thread t1 = new Thread(new ThreadStart(plus));
Thread t2 = new Thread(new ThreadStart(minus));
t1.Start();
t2.Start();
}
}
简单线程学习。
静态私有对象tLock = new object();
lock(tLock)<<参数值,为什么要使用对象参数?
答案 0 :(得分:6)
为什么在lock
上有一个对象自变量?
好吧,因为它很方便。
首先,在您的代码示例中显而易见的是,在lock
的调用之间需要某种共享状态,以声明代码的两个不同部分是互斥的。如果语法只是lock { }
而没有参数,则如下所示:
public void DoSomestuff()
{
lock
{
// Section A
}
}
public void DoOtherStuff()
{
lock
{
// Section B
}
}
那么所有锁要么是互斥的,要么仅影响它们各自的代码部分(因此,两个线程可以同时执行A和B部分,但一次只能执行一个线程)。这样会大大降低关键字的有效性。
现在我们确定需要一个共享状态,这个状态应该是什么?我们可以使用一个字符串:
lock ("My Section")
{
// Section A
}
它可以工作,但有一些缺点:
.NET作者改为使用对象参数。这解决了问题1 /,因为您知道除非您愿意,否则另一个库将不会引用您的对象。但这也解决了问题2,因为这允许运行时将锁存储在实际的对象头中。这是一个非常整洁的优化。
答案 1 :(得分:1)
请考虑以下内容(不带锁):
for (int i = 0; i < 1000; i++)
{
count++;
Console.WriteLine("plus " + count);
Thread.Sleep(1);
}
如果两个线程同时运行:
count
添加一个,现在为1。count
添加一个,现在为2。plus 2
并循环,然后再次向count
添加一个,现在为3。plus 3
,这是不想要的,因为在调用count
时WriteLine
为1。添加锁定机制(lock
)时,开发人员确保代码的一部分为atomic
,即按顺序运行而不会中断。
for (int i = 0; i < 1000; i++)
{
lock (tLock)
{
count++;
Console.WriteLine("plus " + count);
Thread.Sleep(1);
}
}
如果在此遵循相同的模式:
count
添加一个,现在为1。lock
。 plus 1
并释放锁。count
,现在为2。lock
。 plus 2
并释放锁。如您所见,增量和WriteLine
现在是同步操作。
修改
更改问题后:
lock
关键字需要一个reference type对象。它不必是object
。也可以是class
,interface
,delegate
,dynamic
或string
。
public static string a = string.Empty;
public static void Main()
{
lock(a)
{
Console.WriteLine("Hello World");
}
}
有关更多信息,请参见documentation。