1:你可以呼叫執行緒的例項方法join來等待乙個執行緒的結束。例如:
public
static
void
mainthread()
static
void
go()
在列印了
1000個y
之後,後面就會輸出
」thread t has ended!」.,
你可以在呼叫
join
方法的時候給它乙個
timeout
的引數,例如要超時一秒:
t.join(
1000
);t.join(timespan.fromseconds(
1));
2:為執行緒傳遞引數
為執行緒傳遞引數的最簡單的方法莫過於執行乙個
lambda
表示式,然後在方法裡面給引數了,例如:
static
void
main()
static
void
print(
string
message)
使用這種方法,你可以傳遞任何引數。
當然thread的建構函式中有乙個傳遞引數的版本,你也可以使用下面的**來傳遞引數:
static
void
main()
static
void
print(
object
messageobj)
這裡有一點要注意,因為
的方法簽名必須匹配
parameterizedthreadstart
委託,
而parameterizedthreadstart
的引數是
object
,所以print
的引數必須也是
object
,所以在
方法中必須進行強制轉換。
3:lambda和捕獲的變數。
考慮下下面的**:
for(inti =
0; i
<
10; i++)
實際的輸出是不確定的,例如可能是
0113348899.
為什麼???
關鍵的問題是區域性變數i在for迴圈中指向的是相同的記憶體位址.因此,每一次都在乙個執行時會被改變值的變數(i)上呼叫console.write方法,
在foreach中也存在相同問題。
解決這個問題的方法很簡單,例如使用乙個臨時的變數。例如:
for(inti =
0; i
<
10; i++)
因為i是值型別,所以int temp=i 會複製i的值給temp,而在for迴圈中temp變數都是不同的,所以可以解決這個問題。
下面的也是同樣的道理:
for(inti =
0; i
<
10; i++)
下面的例子可能更明顯一些:
string
text ="
t1";thread t1
=new
thread(()
=>
console.writeline(text));
text ="
t2";thread t2
=new
thread(()
=>
console.writeline(text));
t1.start();
t2.start();
因為兩個
lambda
表示式捕獲的是相同的
text
變數,所以
「t2」
會被列印兩次。
output:
t2t2
4:命名執行緒:
但是你只能設定一次執行緒的名字,嘗試在以後更改名字會丟擲乙個異常,為變數命名的使用的是name屬性,例如:
thread worker
=new
thread(go);
worker.name
=」worker」;
worker.name
=」worker」;
//會丟擲異常
5 :前台執行緒和後台執行緒:
預設你顯示建立的執行緒都是前台執行緒。
只要前台執行緒有乙個還在執行,應用程式就不會結束。
只有所有的前台執行緒都結束了,應用程式才會結束,
在應用程式結束的時候,所有後台執行緒都會被終止。
你可以通過執行緒的
isbackground
屬性來查詢和更改執行緒的狀態。這裡是乙個例子。
static
void
main(
string
args) 如果
args.length>0
,則worker
就是後台執行緒,那麼應用程式會立即終止。
否則worker
預設就是前台執行緒,所以只有在
console.readline()
方法結束後,應用程式才會終止。
所以當你有時候發現關閉了應用程式視窗,但是在任務管理器中應用程式仍然在執行,很有可能就是還有一些前台執行緒在執行。
6: 執行緒的優先順序:
enum threadpriority
只有在多個執行緒的環境下,執行緒優先順序才有用。
把乙個執行緒的優先順序提高並不會提高實時系統的效能,因為程序的優先順序才是應用程式的瓶頸。為了更好的實時工作,你必須提高程序的優先順序。
例如process.priorityclass=processpriorityclass.high.
7: 異常捕獲:
嘗試在乙個執行緒中捕獲另乙個執行緒的異常時失敗的。例如:
public
static
void
main()
catch
(exception ex)
}static
void
go()
我們在另乙個執行緒中丟擲了異常
(throw null;),
然後嘗試在主線程中捕獲它,我們永遠都不到這個異常。
為了在另乙個執行緒中捕獲異常,必須在那個執行緒上
try,catch,finally.
所以可以將**改為下面的方式:
public
static
void
main()
static
void
go()
catch
(exception ex)}
8:全域性捕獲異常:
事件和事件都只有在主
ui執行緒中丟擲異常的時候才會被觸發。
為了捕獲所有的未處理的異常,你可以使用
雖然這個事件在任何未處理異常丟擲的時候都會被觸發,但是它不能讓你阻止應用程式的關閉。
深入淺出多執行緒系列之二 關於Thread的那些事
1 你可以呼叫執行緒的例項方法join來等待乙個執行緒的結束。例如 public static void mainthread static void go 在列印了 1000個y 之後,後面就會輸出 thread t has ended 你可以在呼叫 join 方法的時候給它乙個 timeout ...
深入淺出多執行緒系列之三 執行緒池
執行緒池 每乙個執行緒缺省會被分配 1mb的記憶體,在 c 中,這些都是實打實的分配的,當乙個執行緒啟動的時候,為了分配臨時堆疊大約需要花費幾百微秒的時間。執行緒池通過迴圈利用執行緒可以讓你更高效的利用執行緒。執行緒池就像外包的勞務隊一樣,有任務給他們,他們會管理勞務工的一切,你不需要去花時間去找單...
深入淺出多執行緒系列之三 執行緒池
執行緒池 每乙個執行緒缺省會被分配 1mb的記憶體,在 c 中,這些都是實打實的分配的,當乙個執行緒啟動的時候,為了分配臨時堆疊大約需要花費幾百微秒的時間。執行緒池通過迴圈利用執行緒可以讓你更高效的利用執行緒。執行緒池就像外包的勞務隊一樣,有任務給他們,他們會管理勞務工的一切,你不需要去花時間去找單...