C# Lock锁保正多线程环境下的数据一致性
Posted 何以解忧 `唯有暴富
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C# Lock锁保正多线程环境下的数据一致性相关的知识,希望对你有一定的参考价值。
C#中支持多线程,而多线程引发的一个比较突出的问题就是在同一个时间里,可能会有多个线程访问同一个资源,引起资源的竞争导致数据内容超出预期。
我们建立一个对象,然后在对象里增加一个线程id打印的方法,因为这个_threadId = threadId赋值没有锁,可以多线程访问,输出时可能被另一个线程改掉
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace LockTest
{
public class LockClass
{
private string _threadId;
public void Test(string threadId)
{
_threadId = threadId;
Random random = new Random();
Thread.Sleep(random.Next(1000, 2000));
Console.WriteLine("ThreadId:" + Thread.CurrentThread.ManagedThreadId.ToString() + " _threadId:" + _threadId + "第一层锁");
Thread.Sleep(random.Next(1000,2000));
}
}
}
结果那是一片混乱
调用代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace LockTest
{
class Program
{
private static LockClass lockClass = new LockClass();
static void Main(string[] args)
{
Thread t1;
Thread t2;
Thread t3;
t1 = new Thread(SetInfo1);
t2 = new Thread(SetInfo2);
t3 = new Thread(SetInfo3);
t1.Start();
t2.Start();
t3.Start();
}
public static void SetInfo1()
{
while (true)
{
lockClass.Test(Thread.CurrentThread.ManagedThreadId.ToString());
}
}
//偶数线程
public static void SetInfo2()
{
while (true)
{
lockClass.Test(Thread.CurrentThread.ManagedThreadId.ToString());
}
}
public static void SetInfo3()
{
while (true)
{
lockClass.Test(Thread.CurrentThread.ManagedThreadId.ToString());
}
}
}
}
我们给他加上锁看下结果如何,结果井然有序
代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace LockTest
{
public class LockClass
{
private object _sign = new object();
private string _threadId;
public void Test(string threadId)
{
lock (_sign)
{
_threadId = threadId;
Random random = new Random();
Thread.Sleep(random.Next(1000, 2000));
Console.WriteLine("ThreadId:" + Thread.CurrentThread.ManagedThreadId.ToString() + " _threadId:" + _threadId + "第一层锁");
Thread.Sleep(random.Next(1000, 2000));
}
}
}
}
如果我们在锁中加同一把锁会有什么事情发生么,lock 关键字可以用来确保代码块完成运行,而不会被其他线程中断。这是通过在代码块运行期间为给定对象获取互斥锁来实现的。在同一个线程内,锁中的同一把锁会被无视。
在lock内加lock
lock (_sign) {
lock (_sign){}
}
代码如下
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace LockTest
{
public class LockClass
{
private object _sign = new object();
private string _threadId;
public void Test(string threadId)
{
lock (_sign)
{
_threadId = threadId;
lock (_sign)
{
Random random = new Random();
Thread.Sleep(random.Next(1000, 2000));
Console.WriteLine("ThreadId:" + Thread.CurrentThread.ManagedThreadId.ToString() + " _threadId:" + _threadId + "第一层锁");
Thread.Sleep(random.Next(1000, 2000));
}
}
}
}
}
结果相同
以上是关于C# Lock锁保正多线程环境下的数据一致性的主要内容,如果未能解决你的问题,请参考以下文章