C# 多线程如何访问同一个数据

C# 使用Monitor类、lock和Mutex类进行多线程同步

  1. 在多线程中,为了使数据保持一致性必须要对数据或是访问数据的函数加锁,在数据库中这是很常见的,但是在程序中大部分都是单线程的程序,所以没有加锁的必要,但是在多线程中,为了保持数据的同步,一定要加锁。
  2. 在Framework中已经为我们提供了三个加锁的机制,分别是Monitor类、lock关键字和Mutex类。
  3. Monitor和lock用法差不多,都是锁定数据或是锁定被调用的函数。Mutex多用于锁定多线程间的同步调用。
  4. Mutex只能互斥线程间的调用,但是不能互斥本线程的重复调用。运行下面程序,可以看出thread1中waitOne()只对thread2中的waitOne()起到互斥的作用,但是thread1并不受waitOne()的影响,可以调用多次,只是在调用结束后调用相同次数的ReleaseMutex()就可以。
private void thread1Func() 
    { 
        for (int count = 0; count < 10; count++) 
        { 
            mutex.WaitOne(); 
            TestFunc("Thread1 have run " + count.ToString() + " times"); 
            mutex.ReleaseMutex(); 
        } 
    } 
    private void thread2Func() 
    { 
        for (int count = 0; count < 10; count++) 
        { 
            mutex.WaitOne(); 
            TestFunc("Thread2 have run " + count.ToString() + " times"); 
            mutex.ReleaseMutex(); 
        } 
    } 
    private void TestFunc(string str) 
    { 
        Console.WriteLine("{0} {1}", str, System.DateTime.Now.Millisecond.ToString()); 
        Thread.Sleep(50); 
    } 
  1. 那么如何使线程按照调用顺序来依次执行呢?其实把lock和Mutex结合起来使用就可以了。
private void thread1Func() 
{ 
    for (int count = 0; count < 10; count++) 
    { 
        lock (this) 
        { 
            mutex.WaitOne(); 
            TestFunc("Thread1 have run " + count.ToString() + " times"); 
            mutex.ReleaseMutex(); 
        } 
    } 
} 
private void thread2Func() 
{ 
    for (int count = 0; count < 10; count++) 
    { 
        lock (this) 
        { 
            mutex.WaitOne(); 
            TestFunc("Thread2 have run " + count.ToString() + " times"); 
            mutex.ReleaseMutex(); 
        } 
    } 
}

C# 多线程 Mutex(互斥锁)

  1. 互斥锁
    a. 互斥锁是一个互斥的同步对象,意味着同一时间有且仅有一个线程可以获取它。
    b. 互斥锁可适用于一个共享资源每次只能被一个线程访问的情况。

ConcurrentDictionary<TKey, TValue> 类

表示可由多个线程同时访问的键/值对的线程安全集合。

任务方法用法说明
添加的Key值在字典内不存在TryAdd如果当前不在字典中存在该键,此方法见刚添加制定键/值对。改方法返回true或false具体取决于是否已添加新对。
如果改注册表项具有特定值,更新为现有键在字典中值TryUpdate此方法检查是否Key具有指定的值,如果它存在,则用新值更新该键。
无条件地将键/值对存储在字典中,覆盖已存在的键的值dictionary[key]=newValue
将键/值对添加到字典中,或如果Key已存在,更新基于键的现有值的键的值AddOrUpdateAddOrUpdate(TKey, Func, Func) 接受的键和两个委托。 如果键在字典; 中不存在,则使用第一个委托它接受键并返回应添加的键的值。 如果该键不存在; 它使用第二个委托它接受的键和其当前值,并返回应为项设置的新值。AddOrUpdate(TKey, TValue, Func) 接受键、 值要添加,以及更新委托。 这是与以前的重载中,相同之处在于它不使用委托来添加的键。
获取此键在字典中,向字典中添加值并将其返回如果该键不存在的值GetOrAdd这些重载提供延迟初始化为键/值对在字典中,添加的值,仅当不存在。GetOrAdd(TKey, TValue) 采用键不存在要添加的值。GetOrAdd(TKey, Func) 将一个委托,可将生成的值,如果键不存在。
  • 6
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值