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

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

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

你可能感兴趣的:(编程过程总结小知识,网络编程)