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