在Java中,為了生成一個線程,有兩種方法:

  1. 繼承Thread類,覆蓋run方法。在使用時,調用Thread實例的start方法即可啟動一個線程,此線程將執(zhí)行run方法里面的代碼。
  2. 實現(xiàn)Runnable接口,實現(xiàn)run方法。在使用時,調用Thread實例(傳入實現(xiàn)Runnable接口的類實例)的start方法,此線程將執(zhí)行run方法里面的代碼。

啟動線程的方法只能用start方法,不能用run方法...start方法才會啟動一個線程去執(zhí)行run方法,而run方法僅僅是一個類實例的方法!!!

在此,需要強調的是,線程和Thread類的區(qū)別。線程是一個動態(tài)的概念,而Thread類(或其實例)是靜態(tài)的概念。雖然說從代碼上看,執(zhí)行Thread實例的start方法或者run方法(只能在實現(xiàn)Runnable接口時)好像把Thread實例當作了一個線程,當事實上,應該這樣理解:Thread類就是一個普通的類,和其他類沒有什么兩樣,但是他的start方法或者run方法比較特殊,可以啟動一個新的線程。當新線程啟動后,就馬上執(zhí)行Thread類里面run方法的代碼或者Runnable接口的run方法。 在Java中,為了實現(xiàn)多線程之間的同步和互斥,提供了一個關鍵字,synchronized。這個關鍵字有兩個用法:

  1. 用于方法聲明中。如: public synchronized void methd(){ .... } 把這種用法稱之為synchronized方法。
  2. 用于方法體中。如: public void method(){ synchronized(this){ .... } }把這種方法稱為synchronized語句。

當不同的線程運行synchronized方法或者synchronized語句時,首先會獲得鎖,然后再執(zhí)行,當退出時,會釋放鎖。當鎖還沒有被釋放時,如果有其他線程訪問,那么這些線程會阻塞。如果鎖被釋放,那么jvm會讓所有在此鎖上阻塞的所有線程競爭,將有一個線程得到鎖,其他線程將繼續(xù)阻塞。 其實,synchronized方法就是在方法體的最前面加了一個鎖,在方法體的最后面釋放掉了這個鎖。synchronized語句就是在被包含的語句 前加了一個鎖,在被包含的語句后釋放掉了鎖。這里需要強調鎖的概念,可以這么認為,Java中每一個對象都有一個鎖的,可以使用synchronized 方法和synchronized語句來獲得這些鎖。 下面通過實例來理解synchronized方法和synchronized語句。 1,下面的兩個方法是等價的: public synchronized void methd(){ .... } public void method(){ synchronized(this){ .... } } 怎么理解上面的等價? synchronized方法(只能)獲得當前對象的鎖,那么,在synchronized語句中顯示的指明要獲得鎖的對象為this就可以使兩者等價了。 在synchronized方法中,多個線程同時只能訪問某個對象(可能含多個synchronized方法)的一個synchonized方法。 對下面這個銀行類來說,使用synchronized方法就可以達到線程的互斥。多個線程同時只能有一個線程訪問一個synchronized方法。 public class Bank{ public synchronized void deposite(){ 對某個帳戶進行增加 } public synchronized void withdraw(){ 對某個帳戶進行減少 } } 如果,我們想對某個對象的方法進行更靈活的線程互斥訪問,可以使用synchornized語句,顯示的聲明要獲得的鎖的對象。 2, public synchronized static  void methd(){ .... } 上面的方法都可以防止多個線程同時訪問這個類中的method方法。它可以對類的所有對象實例起作用。他等價于下面的方法。 public static  void method(){ synchronized(this.getClass()){ .... } } 這里還需要補充一下,synchronized方法被繼承后就不是synchronized的了,除非在子類中再次聲明方法為synchronized的。 Object類是Java所有對象的基類,Object類中有幾個方法,提供了對多線程編程的支持:

  1. wait()方法將當前運行的線程阻塞,放置于當前線程鎖執(zhí)行的對象的wait set中,然后取消此線程對鎖的獲得。
  2. notify()/notifyAll()方法將把當前線程執(zhí)行的對象的wait set中的某一個/所有線程拿出來。

注意,wait和notify/notifyAll方法只能在線程已獲得對象實例的鎖時才能調用,否則,將拋出java.lang.IllegalMonitorStateException。 這篇文章寫的好累啊,語言組織能力咋這么弱...


文章來源:http://localhost/wp2/?p=52