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

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

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

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

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

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

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

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


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