前言
初學者學習編程時,很容易因為多線程出現各種問題,導致不敢使用多線程。但是多線程技術在做開發中,是不可忽視的一個技術,基本上我們實際應用中,每個項目都會使用多線程,所以多線程技術必須掌握。
為什么要用多線程
隨著工業的進步,現在的筆記本、臺式機大都是雙核的,4核、8核甚至16核,也很常見,如果是單線程的程序,那么在雙核CPU上就浪費了50%,在4核CPU上就浪費了75%。
單核CPU上所謂的”多線程”那是假的多線程,同一時間處理器只會處理一段邏輯,只不過線程之間切換得比較快,看著像多個線程”同時”運行罷了。
多核CPU上的多線程才是真正的多線程,它能讓你的多段邏輯同時工作,多線程,可以真正發揮出多核CPU的優勢來,達到充分利用CPU的目的。
如果你做項目不使用多線程,不僅是技術的問題,也是對電腦資源的極大浪費,就像你買了一輛配置非常高的越野車,你僅僅只用它來日常代步一樣。3
為什么不敢用多線程
之前跟一些學員溝通時發現,很多學員之所以不敢使用多線程,是因為之前出過問題,有種“一朝被蛇咬,十年怕井繩”的感覺。
為什么多線程容易出問題,有個主要的原因在于多線程充滿著“未知性”,有的人使用時,發現代碼并沒有按照預想的流程在走,這其實是正常的。
我們必須要明確一點,多線程確實是“不可控的”,有某種意義上來說,多線程是靠CPU調度來執行的,并非人為去控制。
我們所謂的控制多線程,僅僅是.NET框架開放了一些接口給開發者,這樣可以相對性地間接控制多線程的啟動停止暫停繼續。
線程的啟動停止
線程的啟動停止,從.Net Framework 4.5開始,Task提供了一個叫CancellationTokenSource的對象,可以使用它來對多線程的啟停進行控制。
首先,我們做一個線程任務,這個任務很簡單,只是不斷操作某個變量,每0.1秒加1,到一定值之后,重置為0,然后將這個值顯示在界面上,界面如下所示:
所以任務方法如下:
個對象就是CancellationTokenSource的對象,因此我們需要創建一個CancellationTokenSource對象cts:
然后在啟動線程按鈕的事件里,編寫代碼如下:
停止線程按鈕的事件里,只需要調用cts的Cancel方法即可:
其實,說白了,就是通過cts來控制cts的IsCancellationRequested屬性,進而實現多線程的控制。
線程的暫停繼續
多線程的暫停繼續,.NET為我們提供了另外一個對象——ManualResetEvent,這個對象會有一個值,這個值是布爾類型,就像一個門閘一樣,True是打開門閘,False是關閉門閘,所以想要暫停多線程就調用這個對象的Reset方法,想要繼續多線程就調用這個對象的Set方法,使用非常簡單。
首先我們創建一下這個對象,可以通過構造方法,給這個對象賦初始值,我這里為True,這樣就能直接運行,不會阻塞。
但是如果希望這個對象與多線程有所聯系,必須要在多線程的方法里體現這個對象的作用,這個是調用這個對象的WaitOne方法,表示在調用的地方阻塞住,通過判斷True或者False來決定是否繼續執行,就像大家開車過高速收費站一樣,即使現在普遍采用ETC了,在入口也需要減速,有一個ETC識別的過程,識別成功才會抬桿,識別識別,桿子是不會自動抬起的,這個是一樣的道理。
所以線程執行代碼如下:
對比一下,其實就是加了一個manual.WaitOne()。
線程暫停代碼:
線程繼續代碼:
AutoResetEvent
AutoResetEvent和ManualResetEvent的用法非常相似,區別在于一個是手動,一個是自動,AutoResetEvent會在置位之后自動復位,這樣體現在多線程里,就是會只執行一次,就像大家進小區一樣,如果有10輛車在排隊,這時候如果自動模式,每次只能進一輛車,如果是手動模式,可以由保安控制門閘打開,等10輛車都進去之后,再由保安將門閘關注。
-
多線程
+關注
關注
0文章
278瀏覽量
19972 -
代碼
+關注
關注
30文章
4789瀏覽量
68640
發布評論請先 登錄
相關推薦
socket 多線程編程實現方法
Python中多線程和多進程的區別
![Python中<b class='flag-5'>多線程</b>和多進程的區別](https://file1.elecfans.com/web2/M00/0A/EF/wKgaomcYcmaAS08XAAAsH7JtzO0544.png)
從多線程設計模式到對 CompletableFuture 的應用
![從<b class='flag-5'>多線程</b>設計模式到對 CompletableFuture 的應用](https://file1.elecfans.com//web2/M00/F3/06/wKgZomZ7sqGAdXtoAASyuO6RCrc135.png)
bootloader開多線程做引導程序,跳app初始化后直接進hardfualt,為什么?
鴻蒙OS開發實例:【ArkTS類庫多線程CPU密集型任務TaskPool】
![鴻蒙OS開發實例:【ArkTS類庫<b class='flag-5'>多線程</b>CPU密集型任務TaskPool】](https://file1.elecfans.com/web2/M00/C6/C5/wKgaomYCyYKAZp6HAAB4LWPdpdQ014.jpg)
鴻蒙APP開發:【ArkTS類庫多線程】TaskPool和Worker的對比
![鴻蒙APP開發:【ArkTS類庫<b class='flag-5'>多線程</b>】TaskPool和Worker的對比](https://file1.elecfans.com/web2/M00/C5/CD/wKgZomYCdwyAIFf5AAB_7E1pFms943.jpg)
鴻蒙原生應用開發-ArkTS語言基礎類庫多線程I/O密集型任務開發
java實現多線程的幾種方式
python中5種線程鎖盤點
![python中5種<b class='flag-5'>線程</b>鎖盤點](https://file1.elecfans.com/web2/M00/C2/F3/wKgZomXpMAiAG5WEAAANt1SVDaM222.jpg)
評論