下面详细讲解一下C#中volatile与lock关键字的用法。
volatile关键字的用法
简介
在多线程编程中,由于CPU对内存的读写可能存在缓存,当多个线程同时操作同一个变量时,就可能出现线程安全问题。而volatile关键字则可以保证被修饰的变量在多线程操作中的可见性和顺序性,即保证多线程程序中的变量修改都能在所有线程中可见。
用法
volatile int x = 0;
通过在int类型变量前添加volatile
关键字,可以保证在多线程编程中访问的时候,读到的永远是最新的值,不能被其它线程缓存。volatile
关键字只能修饰基本数据类型和引用类型,不能修饰方法和类。
示例说明
首先,我们定义一个共享变量x
,并用两个线程对其进行赋值和修改,然后将x
打印出来。
volatile int x = 0;
static void Main(string[] args)
{
Thread t1 = new Thread(() => {
for (int i = 0; i < 100000; i++)
{
x++;
}
});
Thread t2 = new Thread(() => {
for (int i = 0; i < 100000; i++)
{
x++;
}
});
t1.Start();
t2.Start();
t1.Join();
t2.Join();
Console.WriteLine(x);
Console.ReadLine();
}
在这里,我们使用了volatile
关键字修饰int
类型的变量x
,并创建了两个线程共同对其进行操作。运行程序,输出的结果为200000,即可见性和顺序性得到了保证。
lock关键字的用法
简介
lock关键字实现的是互斥锁,即在多线程编程中,当一个线程获取了锁之后,其它线程无法再对其进行修改,直到该线程释放锁为止。
用法
private static readonly object locker = new object();
lock (locker)
{
// 代码块
}
通过使用lock关键字,可把一段代码块变成互斥代码块,在同一时间仅允许一个线程进行访问,其他的线程会被阻塞,等待锁的释放。需要注意的是,lock关键字只能用于引用类型,不能用于值类型。
示例说明
我们定义了一个数字类,在其中封装了一个字段num,以及对该字段进行加10的方法IncreaseNum
。
class Number
{
private int num = 0;
private static readonly object locker = new object();
public void IncreaseNum()
{
lock (locker)
{
num += 10;
Console.WriteLine(num);
}
}
}
我们同时创建了100个线程,每个线程调用一次IncreaseNum
方法。在此过程中,将会同时有多个线程对 num 进行累计,但是由于加了 lock,所以每次只有一个线程在进行访问,保证了线程安全。
Number n = new Number();
Thread[] threads = new Thread[100];
for (int i = 0; i < 100; i++)
{
threads[i] = new Thread(() => {
n.IncreaseNum();
});
}
foreach (Thread t in threads)
{
t.Start();
}
foreach (Thread t in threads)
{
t.Join();
}
Console.ReadLine();
以上就是C#中volatile与lock关键字的用法和相应的示例说明。通过不断的练习和实践,可以更好地掌握多线程编程中的技巧和技巧。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C#中volatile与lock用法 - Python技术站