日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

浅解多线程

發(fā)布時間:2025/3/17 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 浅解多线程 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

多線程的相關概念


1.進程:是操作系統(tǒng)結構的基礎;是一個正在執(zhí)行的程序;計算機中正在運行的程序實例;可以分配給處理器并由處理器執(zhí)行的一個實體;由單一順序的執(zhí)行顯示,一個當前狀態(tài)和一組相關的系統(tǒng)資源所描述的活動單元。

2.線程:線程是程序中一個單一的順序控制流程。是程序執(zhí)行流的最小單元。另外,線程是進程中的一個實體,是被系統(tǒng)獨立調度和分派的基本單位,線程自己不擁有系統(tǒng)資源,只擁有一點在運行中必不可少的資源,但它可與同屬一個進程的其它線程共享進程所擁有的全部資源。一個線程可以創(chuàng)建和撤消另一個線程,同一進程中的多個線程之間可以并發(fā)執(zhí)行。由于線程之間的相互制約,致使線程在運行中呈現(xiàn)出間斷性。線程也有就緒、阻塞和運行三種基本狀態(tài)。每一個程序都至少有一個線程,若程序只有一個線程,那就是程序本身。

3.多線程:在單個程序中同時運行多個線程完成不同的工作,稱為多線程。


小結:其實更容易理解一點進程與線程的話,可以舉這樣一個例子:把進程理解成為一個運營著的公司,然而每一個公司員工就可以叫做一個線程。每個公司至少要有一個員工,員工越多,如果你的管理合理的話,公司的運營速度就會越好。這里官味一點話就是說。cpu大部分時間處于空閑時間,浪費了cpu資源,多線程可以讓一個程序“同時”處理多個事情,提高效率。


單線程問題演示


創(chuàng)建一個WinForm應用程序,這里出現(xiàn)的問題是,點擊按鈕后如果在彈出提示框之前,窗體是不能被拖動的。

private void button1_Click(object sender, EventArgs e){for (int i = 0; i < 10000000000; i++) {i += 1;}MessageBox.Show("出現(xiàn)后能拖動,提示沒出現(xiàn)之前窗體不能被拖動");}

原因:運行這個應用程序的時候,窗體應用程序自帶一個叫做UI的線程,這個線程負責窗體界面的移動大小等。如果點擊按鈕則這個線程就去處理這個循環(huán)計算,而放棄了其它操作,故而窗體拖動無響應。這就是單線程帶來的問題。

解決辦法:使用多線程,我們自己創(chuàng)建線程。把計算代碼放入我們自己寫的線程中,UI線程就能繼續(xù)做他的界面響應了。


線程的創(chuàng)建


?線程的實現(xiàn):線程一定是要執(zhí)行一段代碼的,所以要產(chǎn)生一個線程,必須先為該線程寫一個方法,這個方法中的代碼,就是該線程中要執(zhí)行的代碼,然而啟動線程時,是通過委托調用該方法的。線程啟動是,調用傳過來的委托,委托就會執(zhí)行相應的方法,從而實現(xiàn)線程執(zhí)行方法。

//創(chuàng)建線程 private void button1_Click(object sender, EventArgs e){//ThreadStart是一個無參無返回值的委托。ThreadStart ts = new ThreadStart(js);//初始化Thread的新實例,并通過構造方法將委托ts做為參數(shù)賦初始值。Thread td = new Thread(ts); //需要引入System.Threading命名空間//運行委托 td.Start();}//創(chuàng)建的線程要執(zhí)行的函數(shù)。void js(){for (int i = 0; i < 1000000000; i++){i += 1;}MessageBox.Show("提示出現(xiàn)前后窗體都能被拖動");}

把這個計算寫入自己寫的線程中,就解決了單線程中的界面無反應缺陷。


小結:創(chuàng)建線程的4個步驟:1.編寫線程索要執(zhí)行的方法。2.引用System.Threading命名空。3.實例化Thread類,并傳入一個指向線程所要運行方法的委托。4.調用Start()方法,將該線程標記為可以運行的狀態(tài),但具體執(zhí)行時間由cpu決定。


?方法重入(多個線程執(zhí)行一個方法)


?由于線程可與同屬一個進程的其它線程共享進程所擁有的全部資源。

所以多個線程同時執(zhí)行一個方法的情況是存在的,然而這里不經(jīng)過處理的話會出現(xiàn)一點問題,線程之間先后爭搶資源,致使數(shù)據(jù)計算結果錯亂。?

public partial class 方法重入 : Form{public 方法重入(){InitializeComponent();//設置TextBox類的這個屬性是因為,開啟ui線程,//微軟設置檢測不允許其它線程對ui線程的數(shù)據(jù)進行訪問,這里我們把檢測關閉,也就允許了其它線程對ui線程數(shù)據(jù)的訪問。//如果檢測不設置為False,則報錯。TextBox.CheckForIllegalCrossThreadCalls = false;}private void button1_Click(object sender, EventArgs e){textBox1.Text = "0";//開啟第一個線程,對js方法進行計算ThreadStart ts = new ThreadStart(js);Thread td = new Thread(ts);td.Start();//開啟第二個線程,對js方法進行計算ThreadStart ts1 = new ThreadStart(js);Thread td1 = new Thread(ts1);td1.Start();}//多線程要重入的方法。void js(){int a = Convert.ToInt32(textBox1.Text);for (int i = 0; i < 2000; i++){a++;textBox1.Text = a.ToString();}}}?

出錯現(xiàn)象:點擊按鈕后TextBox1中數(shù)據(jù)為2000+或2000,如果你看到的數(shù)據(jù)一直是2000說明你的計算機cpu比較牛X,這樣的話你想看到不是2000的話,你可以多點擊幾次試試,真不行的話,代碼中給TextBox1賦值為0,換做在界面中給textBox1數(shù)值默認值為0試試看。

出錯原因:兩個進程同時計算這個方法,不相干擾應該每個線程計算的結果都是2000的,但是這里的結果輸出卻讓人以外,原因是第一個兩個線程同時計算,并不是同時開始計算,而是根據(jù)cpu決定的哪個先開始,哪個后開始,雖然相差時間不多,但后開始的就會取用先開始計算過的數(shù)據(jù)計算,這樣就會導致計算錯亂。

解決辦法:解決這個的一個簡單辦法解釋給方法加鎖,加鎖的意思就是第一個線程取用過這個資源完畢后,第二個線程再來取用此資源。形成排隊效果。

下面給方法加鎖。

//多線程要重入的方法,這里加鎖。void js(){lock (this){int a = Convert.ToInt32(textBox1.Text);for (int i = 0; i < 2000; i++){a++;textBox1.Text = a.ToString();}}}

給方法加過鎖后,線程一前一后取用資源,就能避免不可預計的錯亂結果,第一個線程計算為2000,第二個線程計算就是從2000開始,這里的結果就為4000。


小結:多線程可以同時運行,提高了cpu的效率,這里的同時并不是同時開始,同時結束,他們的開始是由cpu決定的,時間相差不大,但會有不可預計的計算錯亂,這里要注意類似上面例子導致的方法重入問題。


?前臺線程后臺線程


?.Net的公用語言運行時能區(qū)分兩種不同類型的線程:前臺線程和后臺線程。這兩者的區(qū)別就是:應用程序必須運行完所有的前臺線程才可以退出;而對于后臺線程,應用程序則可以不考慮其是否已經(jīng)運行完畢而直接退出,所有的后臺線程在應用程序退出時都會自動結束。

問題:關閉了窗口,消息框還能彈出。

private void button1_Click(object sender, EventArgs e){ //開啟一個線程,對js方法進行計算ThreadStart ts2 = new ThreadStart(js);Thread td2 = new Thread(ts2); td2.Start();} void js(){for (int i = 0; i < 2000000000; i++) //如果看不出效果這里的2后面多加0 {i++;}MessageBox.Show("關閉了窗口我還是要出來的!");}

原因:.Net環(huán)境使用Thread建立線程,線程默認為前臺線程。即線程屬性IsBackground=false,而前臺線程只要有一個在運行則應用程序不關閉,所以知道彈出消息框后應用程序才算關閉。

解決辦法:在代碼中設置td2.IsBackground=true;


?線程執(zhí)行帶參數(shù)的方法


?

//創(chuàng)建一個執(zhí)行帶參數(shù)方法的線程private void button1_Click(object sender, EventArgs e){//ParameterizedThreadStart這是一個參數(shù)類型為object的委托ParameterizedThreadStart pts=new ParameterizedThreadStart(SayHello);Thread td2 = new Thread(pts);td2.Start("張三"); //參數(shù)值先入這里 }void SayHello(object name){MessageBox.Show("你好,"+name.ToString()+"!");}?

線程執(zhí)行帶多參數(shù)的方法


?

?其實還是帶一參數(shù)的方法,只不過是利用參數(shù)類型為object的好處,這里將類型傳為list類型,貌似多參。

//創(chuàng)建一個執(zhí)行帶多個參數(shù)的方法線程private void button1_Click(object sender, EventArgs e){List<string> list = new List<string> { "張三", "李四", "王五" };//ParameterizedThreadStart這是一個參數(shù)類型為object的委托ParameterizedThreadStart pts=new ParameterizedThreadStart(SayHello);Thread td2 = new Thread(pts);td2.Start(list); //參數(shù)值先入這里 }void SayHello(object list){List<string> lt = list as List<string>;for (int i = 0; i < lt.Count; i++){MessageBox.Show("你好," + lt[i].ToString() + "!");}}?

總結:看到這里相信對多線程應該有一個初步的了解了,我就不說了。

?

?

總結

以上是生活随笔為你收集整理的浅解多线程的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內容還不錯,歡迎將生活随笔推薦給好友。