zoukankan      html  css  js  c++  java
  • .Net 知识点

    .Net 知识点

    Multi Thread (多线程)

    多线程下解决资源竞争的7种方法

    1. 临界区 Lock

    其实是临界区(Monitor)的一个语法糖,通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问。

    private static object obj = new object();
    private static int lockInt;
    private static void LockIntAdd()
    {
        for (var i = 0; i < runTimes; i++)
        {
            lock (obj)
            {
                lockInt++;
            }
        }
    }
    
    1. 互斥量 Mutex

    为协调共同对一个共享资源的单独访问而设计的。在System.Threading命名空间下,Mutex其实就是互斥量,互斥量不单单能处理多线程之间的资源竞争,还能处理进程之间的资源竞争,功能是比较强大的,但是开销也很大,性能比较低。

    private static Mutex mutex = new Mutex();
    private static int mutexInt;
    private static void MutexIntAdd()
    {
        for (var i = 0; i < runTimes; i++)
        {
            mutex.WaitOne();
            mutexInt++;
            mutex.ReleaseMutex();
        }
    }
    
    1. 信号量 Semaphore

    为控制一个具有有限数量用户资源而设计。

    private static Semaphore sema = new Semaphore(1, 1);
    private static int semaphoreInt;
    private static void SemaphoreIntAdd()
    {
        for (var i = 0; i < runTimes; i++)
        {
            sema.WaitOne();
            semaphoreInt++;
            sema.Release();
        }
    }
    
    1. 事件 AutoResetEvent

    用来通知线程有一些事件已发生,从而启动后继任务的开始。

    public static AutoResetEvent autoResetEvent = new AutoResetEvent(true);
    private static int autoResetEventInt;
    private static void AutoResetEventIntAdd()
    {
        for (var i = 0; i < runTimes; i++)
        {
            if (autoResetEvent.WaitOne())
            {
                autoResetEventInt++;
                autoResetEvent.Set();
            }
        }
    }
    
    1. 读写锁 ReaderWriterLockSlim

    这种锁允许在有其他程序正在写的情况下读取资源,所以如果资源允许脏读,用这个比较合适。

    private static ReaderWriterLockSlim LockSlim = new ReaderWriterLockSlim();
    private static int lockSlimInt;
    private static void LockSlimIntAdd()
    {
        for (var i = 0; i < runTimes; i++)
        {
            LockSlim.EnterWriteLock();
            lockSlimInt++;
            LockSlim.ExitWriteLock();
        }
    }
    
    1. 原子锁 Interlocked.CompareExchange

    通过原子操作Interlocked.CompareExchange实现“无锁”竞争。

    private static int isLock;
    private static int ceInt;
    private static void CEIntAdd()
    {
        //long tmp = 0;
        for (var i = 0; i < runTimes; i++)
        {
            while (Interlocked.CompareExchange(ref isLock, 1, 0) == 1) { Thread.Sleep(1); }
    
            ceInt++;
            Interlocked.Exchange(ref isLock, 0);
        }
    }
    
    1. 原子性操作 Interlocked.Increment

    这是一种特例,野外原子性操作本身天生线程安全,所以无需加锁。

    private static int atomicInt;
    private static void AtomicIntAdd()
    {
        for (var i = 0; i < runTimes; i++)
        {
            Interlocked.Increment(ref atomicInt);
        }
    }
    
    1. 使用ConCurrent线程安全的集合
    • ConCurrentQueue
    • Enqueue:在队尾插入元素
    • TryDequeue:尝试删除队头元素,并通过out参数返回
    • TryPeek:尝试将对头元素通过out参数返回,但不删除该元素
    • ConcurrentStack
    • Push:向栈顶插入元素
    • TryPop:从栈顶弹出元素,并且通过out 参数返回
    • TryPeek:返回栈顶元素,但不弹出
    • ConcurrentDictionary
    • AddOrUpdate:如果键不存在,方法会在容器中添加新的键和值,如果存在,则更新现有的键和值。
    • GetOrAdd:如果键不存在,方法会向容器中添加新的键和值,如果存在则返回现有的值,并不添加新值。
    • TryAdd:尝试在容器中添加新的键和值。
    • TryGetValue:尝试根据指定的键获得值。
    • TryRemove:尝试删除指定的键。
    • TryUpdate:有条件的更新当前键所对应的值。
    • GetEnumerator:返回一个能够遍历整个容器的枚举器
    • ConcurrentBag 一个无序的数据结构集,当不需要考虑顺序时非常有用
    • Add:向集合中插入元素
    • TryTake:从集合中取出元素并删除
    • TryPeek:从集合中取出元素,但不删除该元素
    • BlockingCollection 与经典的阻塞队列数据结构类似
    • Add :向容器中插入元素
    • TryTake:从容器中取出元素并删除
    • TryPeek:从容器中取出元素,但不删除。
    • CompleteAdding:告诉容器,添加元素完成。此时如果还想继续添加会发生异常
    • IsCompleted:告诉消费线程,生产者线程还在继续运行中,任务还未完成
  • 相关阅读:
    win10 ubuntu 双系统启动顺序设置
    关于memset的使用
    POJ 2533 最小上升子序列
    Did Pong Lie? (差分系统 判负环)
    HDU 5828 Rikka with Sequence(线段树 开根号)
    SCU
    北邮校赛 I. Beautiful Array(DP)
    北邮校赛 H. Black-white Tree (猜的)
    北邮校赛 F. Gabriel's Pocket Money(树状数组)
    HDU 5862 Counting Intersections(离散化 + 树状数组)
  • 原文地址:https://www.cnblogs.com/Nine4Cool/p/13721915.html
Copyright © 2011-2022 走看看