下面是一个例子
public class Printer
{
// Lock token.
private object threadLock = new object();
public void PrintNumbers()
{
// Use the lock token.
lock (threadLock)
{
...
}
}
}
但是我仍然不知道线程令牌的概念,为什么有必要?线程令牌与C中的信号量是一样的吗?但是对于C程序,信号量仅仅是整数吗?
答案 0 :(得分:0)
lock
是一个互斥体,与C中的POSIX pthread_mutex_lock
和pthread_mutex_unlock
类似。
只允许一段代码同时获取给定对象的锁,因此这是一种同步线程的方式(不一定是最佳方式,但这是一种更加详细和高度上下文相关的答案)。
作为示例,以下代码同时运行多个线程:
var numbers = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
Task.WhenAll(
Task.Run(() =>
{
for (var i = 0; i < 10; i++)
{
numbers[i] += 10;
Thread.Sleep(10);
}
}),
Task.Run(() =>
{
foreach (var i in numbers)
{
Console.Write(i + " ");
Thread.Sleep(10);
}
})
);
由于它们是同时运行的,因此输出类似于:
11 2 13 4 5 6 7 18 9 10
某些数字递增,其他数字不递增,并且每次都不同。
相同的代码将循环包裹在锁中,但是:
object threadLock = new object();
var numbers = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
Task.WhenAll(
Task.Run(() =>
{
lock (threadLock)
{
for (var i = 0; i < 10; i++)
{
numbers[i] += 10;
Thread.Sleep(10);
}
}
}),
Task.Run(() =>
{
lock (threadLock)
{
foreach (var i in numbers)
{
Console.Write(i + " ");
Thread.Sleep(10);
}
}
})
);
这只会输出两件事之一,具体取决于哪个循环首先获取锁:
11 12 13 14 15 16 17 18 19 20
或
1 2 3 4 5 6 7 8 9 10
这两个任务之间没有实际的协调,因此您获得(递增或不递增)哪个设置仅取决于哪个首先获得了锁定。