国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發(fā)設計 > 正文

C#多線程技術總結(同步)

2019-11-14 13:52:23
字體:
來源:轉載
供稿:網(wǎng)友

二、串行(同步):

1.lock、Monitor--注意鎖定的對象必需是引用類型(string類型除外)

示例:

        PRivate static object syncObject = new object();        private static void TaskWork(object i)        {            Console.WriteLine("我是任務:{0}",i);            lock (syncObject)            {                Thread.Sleep(1000);                Console.WriteLine("我是任務:{0},線程ID:{1}",i,Thread.CurrentThread.ManagedThreadId);            }            try            {                Monitor.Enter(syncObject);                Console.WriteLine("我是任務:{0},線程ID:{1}", i, Thread.CurrentThread.ManagedThreadId);            }            finally            {                Monitor.Exit(syncObject);            }        }//調用Task.Factory.StartNew(TaskWork,1);Task.Factory.StartNew(TaskWork, 2);

2.Interlocked

示例:

            int i=1;            Interlocked.Increment(ref i); //增量+1=2;            Console.WriteLine("i當前的值:{0}", i);            Interlocked.Decrement(ref i); //減量-1=0;            Console.WriteLine("i當前的值:{0}", i);            Interlocked.Exchange(ref i, 2);//賦值=2;            Console.WriteLine("i當前的值:{0}",i);            Interlocked.CompareExchange(ref i, 10, 2);//比較交換值,當i=2時,則將i賦值為10;            Console.WriteLine("i當前的值:{0}", i);

3.Mutex--可以實現(xiàn)進程間的同步,甚至是兩個遠程進程間的同步

示例:

            var t1 = new Task(() =>            {                Console.WriteLine("我是第一個任務!");                Mutex m = new Mutex(false, "test");                m.WaitOne();                Console.WriteLine("第一個任務完成!");                m.ReleaseMutex();            });            var t2 = new Task(() =>            {                Console.WriteLine("我是第二個任務!");                Mutex m = new Mutex(false, "test");                m.WaitOne();                Console.WriteLine("第二個任務完成!");                m.ReleaseMutex();            });            t1.Start();            t2.Start();

 4.ReaderWriterLock 、ReaderWriterLockSlim--如果在某一時刻資源并沒有獲取寫的獨占權,那么可以獲得多個讀的訪問權,單個寫入的獨占權,如果某一時刻已經獲取了寫入的獨占權,那么其它讀取的訪問權必須進行等待. 

示例:

        static ReaderWriterLock rwLock = new ReaderWriterLock();        static void Read(object state)        {            Console.WriteLine("我是讀線程,線程ID是:{0}",Thread.CurrentThread.ManagedThreadId);            rwLock.AcquireReaderLock(Timeout.Infinite);//無限期等待,需要顯式調用ReleaseReaderLock釋放鎖            var readList = state as IEnumerable<int>;            foreach (int item in readList)            {                Console.WriteLine("讀取當前的值為:{0}", item);                Thread.Sleep(500);            }            Console.WriteLine("讀完成,線程ID是:{0}", Thread.CurrentThread.ManagedThreadId);            rwLock.ReleaseReaderLock();                    }        static void Write(object state)        {            Console.WriteLine("我是寫線程,線程ID是:{0}", Thread.CurrentThread.ManagedThreadId);            rwLock.AcquireWriterLock(Timeout.Infinite); //無限期等待,需要顯式調用ReleaseWriterLock釋放鎖            var writeList = state as List<int>;            int lastCount=writeList.Count();            for (int i = lastCount; i <= 10+lastCount; i++)            {                writeList.Add(i);                Console.WriteLine("寫入當前值:{0}",i);                Thread.Sleep(500);            }            Console.WriteLine("寫完成,線程ID是:{0}", Thread.CurrentThread.ManagedThreadId);            rwLock.ReleaseWriterLock();        }    //調用:            var rwList = new List<int>();            var t1 = new Thread(Write);            var t2 = new Thread(Read);            var t3 = new Thread(Write);            var t4 = new Thread(Read);                        t1.Start(rwList);            t2.Start(rwList);            t3.Start(rwList);            t4.Start(rwList);

 

5.SynchronizationAttribute--確保某個類的實例在同一時刻只能被一個線程訪問,類的定義要求:A.類上必需標記SynchronizationAttribute特性,B.類必需繼承自System.ContextBoundObject對象

示例:

    [Synchronization(SynchronizationAttribute.REQUIRED,true)]    public class Account : System.ContextBoundObject    {        private static int _balance;        public int Blance        {            get            {                return _balance;            }        }        public Account()        {            _balance = 1000;        }        public void WithDraw(string name,object money)        {            if ((int)money <= _balance)            {                Thread.Sleep(2000);                _balance = _balance - (int)money;                Console.WriteLine("{0} 取錢成功!余額={1}", name, _balance);            }            else            {                Console.WriteLine("{0} 取錢失?。∮囝~不足!", name);            }        }    }//調用:            var account = new Account();            Parallel.Invoke(() =>            {                account.WithDraw("張三",600);            }, () =>            {                account.WithDraw("李四",600);            });

6.MethodImplAttribute--使整個方法上鎖,直到方法返回,才釋放鎖

示例:

    public class Account    {        private static int _balance;        public int Blance        {            get            {                return _balance;            }        }        public Account()        {            _balance = 1000;        }        [MethodImpl(MethodImplOptions.Synchronized)]        public void WithDraw(string name,object money)        {            if ((int)money <= _balance)            {                Thread.Sleep(2000);                _balance = _balance - (int)money;                Console.WriteLine("{0} 取錢成功!余額={1}", name, _balance);            }            else            {                Console.WriteLine("{0} 取錢失敗!余額不足!", name);            }        }    }//調用            var account = new Account();            Parallel.Invoke(() =>            {                account.WithDraw("張三",600);            }, () =>            {                account.WithDraw("李四",600);            });

7.AutoResetEvent、ManualResetEvent、ManualResetEventSlim--調用WaitOne、WaitAny或WaitAll來使線程等待事件,調用Set方法發(fā)送信號,事件將變?yōu)榻K止狀態(tài),等待的線程被喚醒

示例:

            AutoResetEvent arEvent = new AutoResetEvent(false);//默認為無信號,處于非終止狀態(tài)            Task.Factory.StartNew((o) => {                for (int i = 1; i <= 10; i++)                {                    Console.WriteLine("循環(huán)第{0}次",i);                }                arEvent.Set();//發(fā)送信號,處于終止狀態(tài)            },arEvent);            arEvent.WaitOne();//等待信號,收到信號后則繼續(xù)下面的執(zhí)行            Console.WriteLine("我是主線程,我繼續(xù)執(zhí)行!");            Console.Read();

 8.Sempaphore、SemaphoreSlim(不可跨進程)--信號量,可實現(xiàn)線程、進程間同步

示例:

    public class WashRoom    {        private readonly Semaphore sem;        public WashRoom(int maxUseableCount)        {            sem = new Semaphore(maxUseableCount, maxUseableCount, "WC");        }        public void Use(int i)        {            Task.Factory.StartNew(() =>                {                    Console.WriteLine("第{0}個人等待進入", i);                    // WaitOne:如果還有“空位”,則占位,如果沒有空位,則等待;                    sem.WaitOne();                    Console.WriteLine("第{0}個人成功進入,使用中", i);                    // 模擬線程執(zhí)行了一些操作                    Thread.Sleep(100);                    Console.WriteLine("第{0}個人用完,離開了", i);                    // Release:釋放一個“空位”                    sem.Release();                });        }    }//調用:            var wc = new WashRoom(5);            for (int i = 1; i <= 7; i++)            {                wc.Use(i);            }

9.Barrier--屏障,使多個任務能夠采用并行方式依據(jù)某種算法在多個階段中協(xié)同工作,即:將一個階段的事情分成多個線程來異步執(zhí)行,執(zhí)行完畢后再同時進入下一個階段

示例:

            int taskSize = 5;            Barrier barrier = new Barrier(taskSize, (b) =>            {                Console.WriteLine(string.Format("{0}當前階段編號:{1}{0}", "-".PadRight(15, '-'), b.CurrentPhaseNumber));            });            var tasks = new Task[taskSize];            for (int i = 0; i < taskSize; i++)            {                tasks[i] = Task.Factory.StartNew((n) =>                {                    Console.WriteLine("Task : #{0}   ---->  處理了第一部份數(shù)據(jù)。", n);                    barrier.SignalAndWait();                    Console.WriteLine("Task : #{0}   ---->  處理了第二部份數(shù)據(jù)。", n);                    barrier.SignalAndWait();                    Console.WriteLine("Task : #{0}   ---->  處理了第三部份數(shù)據(jù)。", n);                    barrier.SignalAndWait();                }, i);            }            Task.WaitAll(tasks);

10.SpinLock--自旋鎖,僅限鎖定的時間較短

示例:

            SpinLock sLock = new SpinLock();            int num = 0;            Action action = () =>            {                bool lockTaken = false;                for (int i = 0; i < 10; i++)                {                    lockTaken = false;                    try                    {                        sLock.Enter(ref lockTaken);                        Console.WriteLine("{0}+1={1} ---線程ID:[{2}]", num, ++num,Thread.CurrentThread.ManagedThreadId);                        Thread.Sleep(new Random().Next(9));                    }                    finally                    {                        //真正獲取之后,才釋放                        if (lockTaken) sLock.Exit();                    }                }            };//多線程調用:            Parallel.Invoke(action, action, action);            Console.WriteLine("合計:{0}", num);

11.SpinWait--自旋等待,輕量級

            Thread.Sleep(1000);//線程等待1S;            Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));            SpinWait.SpinUntil(() => false, 1000);//自旋等待1S            Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));            Thread.SpinWait(100000);//指定CPU的循環(huán)次數(shù),時間間隔處決于處理器的運行速度,一般不建議使用            Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));

12.CountdownEvent--與Sempaphore功能類似,但CountdownEvent支持動態(tài)調整信號計數(shù)

 示例:

        static void TimeLimitShopping(int custCount,int times,CountdownEvent countdown)        {            var customers = Enumerable.Range(1, custCount);            foreach (var customer in customers)            {                int currentCustomer = customer;               Task.Factory.StartNew(()=>                {                    SpinWait.SpinUntil(() => false, 1000);                    Console.WriteLine("第{0}波客戶購買情況:Customer-{1}-已購買.", times, currentCustomer);                    countdown.Signal();                });                //countdown.AddCount();            }        }//調用:var countdown = new CountdownEvent(5);                TimeLimitShopping(5, 1, countdown);                countdown.Wait();                countdown.Reset(10);                TimeLimitShopping(10, 2, countdown);                countdown.Wait();                countdown.Reset(20);                TimeLimitShopping(20, 3, countdown);                countdown.Wait();

 最后分享在System.Collections.Concurrent命名空間下的幾個并發(fā)集合類:

ConcurrentBag<T>:表示線程安全的無序集合;

ConcurrentDictionary<T>:表示線程安全的多個鍵值對集合;

ConcurrentQueue<T>:表示線程安全的先進先出集合;

ConcurrentStack<T>:表示線程安全的后進先出集合;

線程的幾個狀態(tài)(以下圖片來源于這篇文章:http://m.survivalescaperooms.com/edisonchou/p/4848131.html):

參考以下相關文章:

歸納一下:C#線程同步的幾種方法

C#編程總結(三)線程同步

 


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 航空| 兴隆县| 犍为县| 吴忠市| 康乐县| 怀集县| 即墨市| 马龙县| 康平县| 兴文县| 和平区| 太原市| 闵行区| 黑河市| 盐城市| 浦东新区| 阜宁县| 定结县| 马龙县| 上杭县| 剑河县| 固镇县| 原平市| 潜江市| 台北县| 灯塔市| 郴州市| 始兴县| 加查县| 紫云| 玛纳斯县| 霍城县| 安泽县| 德格县| 潮州市| 浙江省| 游戏| 淮阳县| 雷波县| 甘孜县| 林西县|