黑龍江 吳文慶 修雅慧
Java語言與C#語言的多線程編程能力和差異
黑龍江 吳文慶 修雅慧
Java與C#是現(xiàn)今網(wǎng)絡(luò)開發(fā)的兩大主要平臺,而多線程編程則是進行并行處理計算中的基礎(chǔ),本文主要闡述了在Java與C#開發(fā)平臺下如何進行多線程編程的方法及注意事項,并且比較和分析兩種開發(fā)平臺下進行多線程編程的差異。
多線程;并行處理;Java;C#
從概念上講,線程提供了一種在一個軟件中并行執(zhí)行代碼的方式——每個線程都“同時”在一個共享的內(nèi)存空間中執(zhí)行指令(當(dāng)然是在一個處理器上,這是通過處于運行狀態(tài)的線程的交替執(zhí)行完成的),因此,每個線程都可以訪問一個程序內(nèi)的數(shù)據(jù)結(jié)構(gòu)。由于這種原因,多線程編程的難度就可想而知了,因為一個程序內(nèi)有許多不同的線程需要安全地共享數(shù)據(jù)。
Java在Java.lang.Thread和Java.lang.Runnable類中提供了大部分的線程功能。創(chuàng)建一個線程非常簡單,就是擴展Thread類,并調(diào)用start()。通過創(chuàng)建一個執(zhí)行Runnable()的類,并將該類作為參數(shù)傳遞給Thread(),也可以定義一個線程。
下面這個簡單的Java程序,其中有2個線程同時在從1數(shù)到5,并將結(jié)果打印出來。
public class ThreadingExample extends Object
{
public static void main(Stringargs[]){
Thread[]threads=new Thread[2];
for(int count=1;count<=threads.length;count){
threads[count]=new Thread(new Runnable()
{
public void run(){
count();
}}
threads[count].start();
}}
public static void count(){
for(int count=1;count<=5;count)
System.out.print(count””);
}
}
可以使用System.Threading.Thread和System.Threading.ThreadStart兩個類將上述的Java程序轉(zhuǎn)換為C#語言:
using System.Threading;
public class ThreadingExample:Object{
public static void Main(){
Thread[]threads=new Thread[2];
for(int count=1;count<=threads.Length;count){
threads[count」=new Thread(new ThreadStart(Count));
threads[count].Start();
}
}
public static void Count(){
for(int count=1;count<=5;count)
Console.Write(count””);
}
}
Java中存在許多編程人員希望能夠?qū)€程使用的標(biāo)準(zhǔn)操作:例如,測試線程是否存在、加人一個線程直到它死亡、殺死一個線程等。
Java中java.lang.Thread中的方法和C#中System.Threading.Thread對象的對比:
setDaemon(boolean on)方法:IsBackground設(shè)置屬性值使一個存在的進程成為一個新線程(如果剩下的所有進程都成了新線程,程序?qū)⑼V惯\行)。
isDaemon()方法:IsBackground 獲取屬性,如果該線程是一個后臺線程,則返回真值。
isAlive()方法:IsAlive獲取屬性,如果該線程處于活動狀態(tài),則返回真值。
Interrupt()方法:盡管在Java中這一方法可以用來設(shè)置線程的中斷狀態(tài),而且可以用來檢查線程是否被中斷。在C#中沒有相應(yīng)的方法,對一個沒有處于阻塞狀態(tài)的線程執(zhí)行Interrupt方法將使下一次阻塞調(diào)用自動失效。
isInterrupted()方法:n/a,如果該線程處于阻塞狀態(tài),則返回真值。
sleep(long millis) 和 sleep(long millis,intnanos),Sleep (int millisecond Timeout)and Sleep(System.TimeSpan)方法:使正在執(zhí)行的線程暫停一段給定的時間,或直到它被中斷。這一方法將在Java中將產(chǎn)生一個java.lang.InterruptedException狀態(tài),在C#中將產(chǎn)生System..Threading.ThreadInterruptedException狀態(tài)。
Join(),join(long millis)和 join(long millis,intnanos)方法與Java中僅依靠超時設(shè)定不同的是,在C#語言中則依據(jù)線程停止運行是由于線程死亡(返回真)或是超時(返回假)而返回一個布爾型變量。
Suspend()方法:二者的功能相同。這一方法容易引起死循環(huán),如果一個占有系統(tǒng)關(guān)健資源的線程被掛起來,則在這一線程恢復(fù)運行之前,其他的線程不能訪問該資源。
Resume()方法:恢復(fù)一個被掛起的線程。
Stop()方法,Abort()方法:參見下面的“線程中止”部分。
由于能夠在沒有任何征兆的情況下使運行的程序進人一種混亂的狀態(tài),Java中的Thread.stop受到了普遍的反對。根據(jù)所調(diào)用的stop()方法,一個未經(jīng)檢查的Java.lang.ThreadDeath錯誤將會破壞正在運行著的程序的棧,隨著它的不斷運行,能夠解除任何被鎖定的對象。由于這些鎖被不分青紅皂白地被打開,由它們所保護的數(shù)據(jù)就非常可能陷人混亂狀態(tài)中。根據(jù)當(dāng)前的Java文檔,推薦的中止一個線程的方法是讓運行的線程檢查一個由其他的線程能夠改變的變量,該變量代表一個“死亡時間”條件。
上述的討論對C#中的Abort方法也適合。根據(jù)調(diào)用的Abort方法,System.Threading.ThreadAbortException可能會破壞線程的棧,它可能釋放線程保持的一些變量,使處于保護狀態(tài)中的數(shù)據(jù)結(jié)構(gòu)出現(xiàn)不可預(yù)測的錯誤。我建議使用與上面所示的相似的方法來通知一個應(yīng)該死亡的線程。
本文章中重點討論了Java和C#在多線程編程方面的具體實現(xiàn)方法,闡述了兩者實現(xiàn)的不同之處,并實現(xiàn)了Java中多線程編程的常用模式轉(zhuǎn)換為C#。
[1]Bruce Eckel(陳昊鵬,譯).Java編程思想(第4版)[M].北京:機械工業(yè)出版社,2007.
[2]Kathy Sierra,Bert Bates.深入淺出Java[M].影印版·南京:東南大學(xué)出版社,2005.
[3]Cay S.Hoistmann,Gary cornell(陳昊鵬,王浩,姚建平,等譯).Java 2核心技術(shù)[M].北京:機械工業(yè)出版社,2006.
(編輯 李艷華)
(作者單位:吳文慶,齊齊哈爾工程學(xué)院;修雅慧,齊齊哈爾醫(yī)學(xué)院)