[置顶] 黑马程序员 -- 多线程
生活随笔
收集整理的這篇文章主要介紹了
[置顶] 黑马程序员 -- 多线程
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
黑馬程序員 -- 多線程
什么是多線程?多線程就是使程序并發(fā)(同時(shí))執(zhí)行幾個(gè)操作。
.NET 框架類庫在System.Threading 中加入了多線程的能力。因此要在前面加入引用 using System.Threading
Thread 類:創(chuàng)建并控制線程,設(shè)置其優(yōu)先級(jí)并獲取其狀態(tài)。
Thread 類的構(gòu)造方法,主要有2中:Thread thread_name=
Thread(ThreadStart):ThreadStart 委托,它表示此線程開始執(zhí)行時(shí)要調(diào)用的方法。適用于無參數(shù)的方法。
Thread(ParameterizedThreadStart):ParameterizedThreadStart 委托,它表示此線程開始執(zhí)行時(shí)要調(diào)用的方法。適用于有參數(shù)傳入的方法。
一個(gè)普通的 無參 線程操作如下:
[csharp] view plaincopyprint?01.Thread td = new Thread(xunhuan);//定義一個(gè)線程,參數(shù)是一個(gè)方法,無返回值,采用的是委托02.03.//前臺(tái)線程,所有的線程都執(zhí)行完了,應(yīng)用程序才退出,默認(rèn)的都是前臺(tái)線程04.//后臺(tái)線程,所有的前臺(tái)線程都執(zhí)行完了,就退出,不管后臺(tái)的線程05.td.IsBackground = true; //設(shè)定為后臺(tái)線程06.td.Start();//啟動(dòng)線程Thread td = new Thread(xunhuan);//定義一個(gè)線程,參數(shù)是一個(gè)方法,無返回值,采用的是委托//前臺(tái)線程,所有的線程都執(zhí)行完了,應(yīng)用程序才退出,默認(rèn)的都是前臺(tái)線程//后臺(tái)線程,所有的前臺(tái)線程都執(zhí)行完了,就退出,不管后臺(tái)的線程td.IsBackground = true; //設(shè)定為后臺(tái)線程td.Start();//啟動(dòng)線程一個(gè)有參的線程如下:[csharp] view plaincopyprint?01.Thread ptd = new Thread(showname);//定義個(gè)線程,傳入的帶參數(shù)的方法。02.ptd.IsBackground = true;03.ptd.Start("lilei");//重載Start方法,傳遞個(gè)參數(shù)Thread ptd = new Thread(showname);//定義個(gè)線程,傳入的帶參數(shù)的方法。ptd.IsBackground = true;ptd.Start("lilei");//重載Start方法,傳遞個(gè)參數(shù)有參的方法定義,參數(shù)objec類型,[csharp] view plaincopyprint?01.//線程調(diào)用,帶多個(gè)參數(shù)02. static void shownames(object names)03. {04. List list = names as List;05. foreach (string name in list)06. {07. MessageBox.Show(name);08. }09.10. }//線程調(diào)用,帶多個(gè)參數(shù)static void shownames(object names){List list = names as List;foreach (string name in list){MessageBox.Show(name);}}------------------------------------------------------------------------線程的狀態(tài)-----------------------------------------------------------------------任何時(shí)候,線程都要處于某種線程狀態(tài)中。新線程在Unstarted狀態(tài)中開始它的生命周期。在調(diào)用Thread類的Start方法之前,會(huì)一直保持在Unstarted狀態(tài),調(diào)用方法之后,就會(huì)進(jìn)入Started狀態(tài),并立即將程序的控制權(quán)返回調(diào)用程序(點(diǎn)了線程調(diào)用后,可以立即去干別的事)。然后,調(diào)用了Start方法的線程(也就是Started線程)和程序中其他的線程并發(fā)執(zhí)行。線程的優(yōu)先級(jí)每個(gè)線程都有個(gè)優(yōu)先級(jí),其范圍在ThreadPriority.Lowest和ThreadPriority.Highest之間。默認(rèn)情況下,每個(gè)線程的優(yōu)先級(jí)都是Normal。Windows操作系統(tǒng)支持時(shí)間分片(timeslicing)的概念,它的思路是優(yōu)先級(jí)相同的線程共享一個(gè)處理器。------------------------------------------------------------------------線程的同步和類監(jiān)視器-----------------------------------------------------------------------通常,多個(gè)執(zhí)行線程要操作共享數(shù)據(jù)。如果有權(quán)訪問共享數(shù)據(jù)的線程只能讀取數(shù)據(jù),那就不需要阻止多個(gè)線程同時(shí)訪問共享數(shù)據(jù)。然而,當(dāng)多個(gè)線程共享數(shù)據(jù),并且其中一個(gè)或多個(gè)線程要修改數(shù)據(jù)時(shí),可能會(huì)出現(xiàn)無法預(yù)知的結(jié)果。如果一個(gè)線程正在更新數(shù)據(jù),另一個(gè)線程也試圖更新,那么數(shù)據(jù)所反映的就第二次更新操作之后的結(jié)果。所以可通過一次只允許一個(gè)線程訪問用于操作共享數(shù)據(jù)的代碼來解決。其他想要操作數(shù)據(jù)的線程應(yīng)該等待。具有排他訪問權(quán)的線程完成對(duì)數(shù)據(jù)的操作后,等待操作線程的數(shù)據(jù)可以繼續(xù)執(zhí)行。這稱為互斥或線程同步。C#提供了兩中解決技術(shù):1.Monitor類:主要方法(方法傳入的參數(shù)為objec對(duì)象,一般為當(dāng)前調(diào)用的線程):Monitor.Enter():獲取排他鎖。Monitor.Wait():釋放對(duì)象上的鎖并阻止當(dāng)前線程,直到重新獲取該鎖。Monitor.Pulse():通知等待隊(duì)列中的線程對(duì)象狀態(tài)的改變。Monitor.Exit():釋放排他鎖。2.lock關(guān)鍵字:在對(duì)象前加個(gè)lock:代碼示例:Monitor的用法:[csharp] view plaincopyprint?01.public class mt02. {03. private int age;04. private int buff = 0;//buff判斷內(nèi)容是否已被更新或提取,0為未更新,1為已更新05. int Age06. {07. get08. {09. Monitor.Enter(this);//獲取此對(duì)象的排他鎖10. if (buff == 0)//若內(nèi)容為空或未更新就使此線程等待11. {12. MessageBox.Show("內(nèi)容為空或未更新");13. Monitor.Wait(this);//釋放鎖并等待14. }15. buff--;16. MessageBox.Show("讀取內(nèi)容");17. Monitor.Pulse(this); //通知等待隊(duì)列的線程,此對(duì)象狀態(tài)要更改18. Monitor.Exit(this);//釋放排他鎖19. return age;20.21. }22. set23. {24. Monitor.Enter(this);25. if (buff == 1)26. {27. MessageBox.Show("內(nèi)容還沒被讀取");28. Monitor.Wait(this);29. }30. buff++;31. MessageBox.Show("寫入內(nèi)容"+value);32. age = value;33. Monitor.Pulse(this);34. Monitor.Exit(this);35. }36. }37. }public class mt{private int age;private int buff = 0;//buff判斷內(nèi)容是否已被更新或提取,0為未更新,1為已更新int Age{get{Monitor.Enter(this);//獲取此對(duì)象的排他鎖if (buff == 0)//若內(nèi)容為空或未更新就使此線程等待{MessageBox.Show("內(nèi)容為空或未更新");Monitor.Wait(this);//釋放鎖并等待}buff--;MessageBox.Show("讀取內(nèi)容");Monitor.Pulse(this); //通知等待隊(duì)列的線程,此對(duì)象狀態(tài)要更改Monitor.Exit(this);//釋放排他鎖return age;}set{Monitor.Enter(this);if (buff == 1){MessageBox.Show("內(nèi)容還沒被讀取");Monitor.Wait(this);}buff++;MessageBox.Show("寫入內(nèi)容"+value);age = value;Monitor.Pulse(this);Monitor.Exit(this);}}}lock的用法:[csharp] view plaincopyprint?01.//lock的用法02. int Age203. {04. get05. {06. lock(this) //開始階段,自獲取了排他鎖07. {08. if (buff == 0)//若內(nèi)容為空或未更新就使此線程等待09. {10. MessageBox.Show("內(nèi)容為空或未更新");11. Monitor.Wait(this);//釋放鎖并等待12. }13. buff--;14. MessageBox.Show("讀取內(nèi)容");15. Monitor.Pulse(this); //通知等待隊(duì)列的線程,此對(duì)象狀態(tài)要更改16. return age;17.18. }//結(jié)束階段,釋放了排他鎖19. }20. set21. {22. lock (this)23. {24. if (buff == 1)25. {26. MessageBox.Show("內(nèi)容還沒被讀取");27. Monitor.Wait(this);28. }29. buff++;30. MessageBox.Show("寫入內(nèi)容" + value);31. age = value;32. Monitor.Pulse(this);33. }34. }35.36. }//lock的用法int Age2{get{lock(this) //開始階段,自獲取了排他鎖{if (buff == 0)//若內(nèi)容為空或未更新就使此線程等待{MessageBox.Show("內(nèi)容為空或未更新");Monitor.Wait(this);//釋放鎖并等待}buff--;MessageBox.Show("讀取內(nèi)容");Monitor.Pulse(this); //通知等待隊(duì)列的線程,此對(duì)象狀態(tài)要更改return age;}//結(jié)束階段,釋放了排他鎖}set{lock (this){if (buff == 1){MessageBox.Show("內(nèi)容還沒被讀取");Monitor.Wait(this);}buff++;MessageBox.Show("寫入內(nèi)容" + value);age = value;Monitor.Pulse(this);}}}-----------------------------------------------------------------lock 與 Monitor 的注意事項(xiàng)------------------------------------------------------------------Monitor注意的地方:用Monitor類的Enter方法和Exit方法來管理對(duì)象的鎖時(shí),要想釋放鎖,必須顯示調(diào)用Exit方法。調(diào)用Exit方法之前如果某個(gè)方法中引發(fā)了一個(gè)異常,并且這個(gè)異常沒有被捕捉到,方法就會(huì)終止,而且不會(huì)調(diào)用Exit方法。因此鎖沒有被釋放。為了避免這種錯(cuò)誤,可以將可能引發(fā)異常的代碼放入一個(gè)try模塊,并將對(duì)Exit方法的調(diào)用放在相應(yīng)的finally塊上以確保釋放鎖。使用一個(gè)Lock塊來管理同步對(duì)象上的鎖,可以避免忘記調(diào)用Monitor類的Exit方法來釋放鎖。Lock處于某種原因二終止時(shí),C#會(huì)隱式調(diào)用Monitor類的exit方法。如此一來,即使在代碼中出現(xiàn)異常,也可以將鎖釋放。 如需更全面地了解編譯器優(yōu)化,請(qǐng)參閱優(yōu)化注意事項(xiàng). RSS Back to Top
Leave a Comment
To Obtain Technical Support, please go to Software Support
你的用戶名 * 電子郵件 * 此內(nèi)容將保密,不會(huì)被其他人看見。 首頁 Comment *作者
polk601001 Black Belt Points: 80Related Content
使用VTune? Amplifier XE 2013工作在Intel? Xeon Phi? coprocessor的一般步驟 2012 英特爾軟件網(wǎng)絡(luò)博客大賽 基于英特爾平臺(tái)的云設(shè)計(jì)與部署(VMware) 基于英特爾平臺(tái)的云設(shè)計(jì)與部署(EMC) 英特爾Hadoop發(fā)行版轉(zhuǎn)載于:https://www.cnblogs.com/wsq724439564/archive/2012/11/13/3258218.html
總結(jié)
以上是生活随笔為你收集整理的[置顶] 黑马程序员 -- 多线程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 全球与中国回音壁市场深度研究分析报告
- 下一篇: 智能阅读模型的构建(第六届泰迪杯C题)