多線程是一個不會過時的話題,因為每個開發(fā)的成長必然要掌握這個知識點,否則半懂不懂怎么保證系統(tǒng)的可靠性和性能,其實在網(wǎng)上隨便一搜都會有海量的文章說這個話題,大多數(shù)寫得很細(xì)寫得非常好,但發(fā)現(xiàn)很少有概覽性的文章,我希望能借本文給大家一個全局視野,結(jié)合多年實踐幫大家快速學(xué)習(xí)或者回顧思考,對感興趣的知識點再深入學(xué)習(xí)了解。

          一、知識點概括



          二、具體實例演示如何實現(xiàn)

          > Thread?多線程最基礎(chǔ)的類
          //ThreadPool.GetMaxThreads(out int maxTCount, out int maxPCount); //
          ThreadPool.GetMinThreads(out int minTCount, out int minPCount);//
          ThreadPool.SetMaxThreads(maxTCount, maxPCount);// 調(diào)整最大線程數(shù) //
          ThreadPool.SetMinThreads(minTCount, minPCount);// 調(diào)整最小線程數(shù) long tick =
          C_ITEM_COUNT; ManualResetEvent signal= new ManualResetEvent(false);
          Console.WriteLine("========== 示例:采用Thread執(zhí)行處理 =========="); for (int i = 0; i <
          C_ITEM_COUNT; i++) { new Thread((obj) => { Thread.Sleep(500); Console.Write("
          {0}", obj); if (Interlocked.Decrement(ref tick) == 0) signal.Set();
          }).Start(i); } Console.Write(" 等待子線程執(zhí)行 "); signal.WaitOne();
          Console.WriteLine(); Console.WriteLine("全部線程執(zhí)行完畢,按任意鍵繼續(xù)...");
          > ThreadPool?線程池,XX池的概念可以廣泛應(yīng)用于其他資源管理,例如字體池(防句柄泄露)、短信貓池等等
          tick = C_ITEM_COUNT; signal.Reset(); Console.WriteLine(); Console.WriteLine("
          ========== 示例:采用ThreadPool執(zhí)行處理 =========="); for (int i = 0; i < C_ITEM_COUNT;
          i++) { ThreadPool.QueueUserWorkItem((obj) => { Thread.Sleep(500); Console.Write(
          " {0} ", obj); if (Interlocked.Decrement(ref tick) == 0) signal.Set(); }, i); }
          Console.Write(" 等待子線程執(zhí)行 "); signal.WaitOne(); Console.WriteLine();
          Console.WriteLine("全部線程執(zhí)行完畢,按任意鍵繼續(xù)...");
          > Task?任務(wù),功能豐富用法靈活。結(jié)合現(xiàn)實生活用字面意思去理解就好:可以同時做多個任務(wù),任務(wù)做完可以接著做其他任務(wù),任務(wù)可能會取消等等。
          tick = C_ITEM_COUNT; signal.Reset(); Console.WriteLine(); Console.WriteLine("
          ========== 示例:采用Task執(zhí)行處理,注意取消了處理{0}的進(jìn)程 ==========", C_ITEM_COUNT - 2); var
          tasks =new Tuple<Task, CancellationTokenSource>[C_ITEM_COUNT]; for (int i = 0;
          i < C_ITEM_COUNT; i++) { var cts = new CancellationTokenSource(); var task =
          Task.Factory.StartNew((obj) => { Thread.Sleep(500); Console.Write(" {0} ",
          obj); }, i, cts.Token); task.ContinueWith((t)=> { if (Interlocked.Decrement(ref
          tick) ==0) signal.Set(); }); tasks[i] = new Tuple<Task, CancellationTokenSource>
          (task, cts); } tasks[C_ITEM_COUNT- 2].Item2.Cancel();// 取消線程。 Console.Write("
          等待子線程執(zhí)行"); signal.WaitOne(); Console.WriteLine(); Console.WriteLine("
          全部線程執(zhí)行完畢,按任意鍵繼續(xù)...");
          > Parallel?并行
          tick = C_ITEM_COUNT; signal.Reset(); Console.WriteLine(); Console.WriteLine("
          ========== 示例:采用Parallel執(zhí)行處理 =========="); Parallel.For(0, C_ITEM_COUNT, obj =>
          { Thread.Sleep(500); Console.Write(" {0} ", obj); if (Interlocked.Decrement(ref
          tick) ==0) signal.Set(); }); Console.Write(" 等待子線程執(zhí)行 "); signal.WaitOne();
          Console.WriteLine(); Console.WriteLine("全部線程執(zhí)行完畢,按任意鍵繼續(xù)...");
          以上示例執(zhí)行結(jié)果如下,重點可以關(guān)注下"等待子線程執(zhí)行"這個節(jié)點,理解主線程和各子線程的優(yōu)先執(zhí)行順序



          三、性能對比(理解線程池技術(shù)的性能也可以通過最大最小線程數(shù)調(diào)節(jié))

          > 循環(huán)數(shù):200,線程池參數(shù):默認(rèn)



          >?循環(huán)數(shù):200,線程池參數(shù):50 - 1000



          >?循環(huán)數(shù)200,線程池參數(shù):100-1000

          ?

          >?循環(huán)數(shù)200,線程池參數(shù):200-1000

          ?

          最大線程數(shù) ~ 最小線程數(shù) Thread(ms) ThreadPool(ms) Task(ms) Parallel(ms)
          2047/1000 ~ 12/12 2712.09 8057.14 8585.01 7526.57
          1000/1000 ~ 50/50 2733.25 2289.96 2218.29 3660.33
          1000/1000 ~ 100/100 2503.08 1620.73 1534.50 1742.78
          1000/1000 ~ 200/200 2999.27 1436.24 1150.21 935.22
          ?四、結(jié)論

          >?Thread就像脫韁的野馬,不受控制,創(chuàng)建多少就運(yùn)行多少,可能少量時效率是高了,量大的時候除了性能沒優(yōu)勢,還可能導(dǎo)致句柄泄露。

          >?ThreadPool與Task類似,但Task相比效率更高用法更靈活。

          >?Parallel自帶了同步功能,不需要用信號量來做額外的同步等待。

          >?ThreadPool、Task、Parallel的性能都取決于線程池最大線程數(shù)和最小線程數(shù)。

          >?推薦使用 Task 和 Parallel,具體用哪個可以參考用法自己斟酌。

          友情鏈接
          ioDraw流程圖
          API參考文檔
          OK工具箱
          云服務(wù)器優(yōu)惠
          阿里云優(yōu)惠券
          騰訊云優(yōu)惠券
          京東云優(yōu)惠券
          站點信息
          問題反饋
          郵箱:[email protected]
          QQ群:637538335
          關(guān)注微信

                久久久aaaa | 国产美女无套 在线播放 | 已婷婷狠狠18禁久久YY | 国产羞羞网站 | 在线免费观看视频一区 |