多執行緒學習

2021-10-11 01:40:37 字數 4644 閱讀 3169

跟前幾篇的風格一樣,我會在開篇的時候舉乙個現實生活中的例子,通過這個例子來對映一些晦澀枯燥的計算機程式設計專業知識,在讓讀者朋友很好地理解理論概念的同時,又避免了閱讀教科書時的枯燥感覺。這次我要舉的例子是公司。不一定是it公司,盡量和程式設計領域遠一點兒吧,那就假設是一家搬家公司吧。

假如我們把公司看做是乙個程序,那麼人就是其中的執行緒。程序必須得有乙個主線程,公司在創業初期往往可能出現一人打天下的現象,但是,至少得有乙個人,公司才能運作。公司創業初期,業務還不算太多,往往就是老闆乙個人身兼數職,一天如果只有1、2趟活兒,應該還是忙得過來的。時間長了,隨著業務的發展、口碑的建立,生意越來越興隆,乙個人肯定就忙不過來了。假設一天有5個活兒,老闆乙個人必須搬完a家才能搬b家,搬到黃昏估計也就搬到c家,d和e家都還在焦急地等待著呢。老闆乙個人要充當搬運工、司機、業務聯絡人、法人代表、出納等眾多角色,累死累活公司的規模也上不去,人手不夠制約了公司的發展。那麼怎麼辦,很簡單,增加人手,用程式設計的話來說就是「再起個執行緒」。

我們現在就用**來描述這樣的場景吧,首先,我們準備成立一家搬家公司,於是要準備好將來和客戶籤的合同書:

1: public class contract
2:
4:     public string from
5:     public string to
6:     public decimal fee
7:
8:     public contract()
9:
12: }

簡是簡單了點兒,好歹也是份合同,現在我們就去申請註冊一家公司,並組建好初創團隊,哪怕目前還只有老闆乙個人:

1: public class housemovingcompany
2:
7:     }
8:
9:     public listcontracts
10:
11:     public housemovingcompany()
12:
15:
16:     public void movehouse()
17:
22:
23:         contract contract = contract = this.contracts[0];
24:         this.contracts.removeat(0);
25:
26:         if (!string.isnullorempty(contract.from) && !string.isnullorempty(contract.to))
27:          to .", contract.from, contract.to);
29:         }
30:
31:         thread.sleep(5000);
32:     }
33: }

好了,現在公司實體有了,老闆就可以開始忙活了:

1: static void main(string args)
2: );
4:
5:     while (housemovingcompany.instance.contracts.count > 0)
6:
9: }

我們在前面設定了每次搬家耗時5秒鐘,咱們把它想象成5個小時。嗯,一天接乙個單子,還可以接受,但是隨著老闆生意日漸興隆,有時候一天要接3個單子,這就最少要工作15個小時了,還要操心公司的運營等問題,的確忙不過來了,而且照這樣算,老闆一天不可能完成5個或5個以上的單子,嚴重制約了公司的發展:

1: static void main(string args)
2: );
4:     housemovingcompany.instance.contracts.add(new contract );
5:     housemovingcompany.instance.contracts.add(new contract );
6:
7:     while (housemovingcompany.instance.contracts.count > 0)
8:
11: }

一天夜裡,老闆拖著疲倦的身子回到家裡,一進門就一頭倒在床上,他極力睜著快睜不開的眼睛,努力地對自己說:「不行,我一定要想個辦法,不然我會被累死的!」。

1: static void main(string args)
2: );
4:     housemovingcompany.instance.contracts.add(new contract );
5:     housemovingcompany.instance.contracts.add(new contract );
6:
7:     thread thread = null;
8:
9:     while (housemovingcompany.instance.contracts.count > 0)
10:
15: }

在這段程式中,我們分頭行動,讓每項搬家任務都由乙個小團隊去完成,結果我們發現,現在做三個單子的時間跟做乙個單子的時間是一樣的,提高了效率也擴大了公司規模。但是,既然引入了新的工作機制,我們在公司內部也不得不做一些小小的調整:

1: public void movehouse()
2:
7:
8:     contract contract = null;
9:
10:     lock (this.contracts)
11:
15:
16:     if (!string.isnullorempty(contract.from) && !string.isnullorempty(contract.to))
17:      to .", contract.from, contract.to);
19:     }
20:
21:     thread.sleep(5000);
22: }

調整的只是movehouse這個方法內部的一些實現細節。公司接到的單子都儲存在contracts中,所以搬家的時候需要去拿乙個單子然後根據單子上的資訊來工作。原先我們只有乙個執行緒在操作contracts,倒也不覺得什麼,現在有多個執行緒都在對contracts中的元素進行訪問,我們不得不提防一些意外發生。這就是在使用多執行緒的時候常常需要考慮的併發問題,所以我們用了lock關鍵字,當乙個執行緒要操作contracts時,它先把contracts鎖起來,其實就是宣告一下:「現在我在操作它,你們誰都不要動,等我弄完了再說。」在lock塊結束時被鎖定的物件才會被解鎖,其它的執行緒現在才可以去操作它。

有了多執行緒機制,你會發現程式可以在更短的時間內完成更多的事情。本文沒有將多執行緒機制中的所有概念面面俱到地列舉出來,但是已經向你展示了該如何使用多執行緒以及什麼時候可以考慮使用多執行緒,其它的一些細節有待你去進一步探索,例如,你可以設定執行緒的優先順序(假設邏輯上跟fee掛鉤,類似於『加急』)等等。

掌握多執行緒機制,並讓它使你的應用程式變得更加強悍吧。

多執行緒學習

thread和runnable的區別 單繼承模式thread 而 runnable是介面 start 和run的區別 start是乙個執行緒只能啟動,run可以執行多次,並且run是呼叫當前正在執行的執行緒 wait notify object物件所具有的 sleep setpriority 同步機...

多執行緒學習

用 編輯 的多執行緒時用gcc threadtest 1.c 編譯時 一直報錯,報錯如下 tmp ccgko5iu.o 在函式 thread create 中 threadtest 1.c text 0x13b 對 pthread create 未定義的引用 threadtest 1.c text ...

多執行緒學習

簡單學習多執行緒。建立多執行緒有兩種方法。一 繼承thread類。多執行緒練習,通過繼承thread public class testthread extends thread public static void main string argsd 二 實現runnable介面。多執行緒練習。通...