java多線程

1.如果在類裏要激活線程,必須先做好下面兩個準備:
(1)線程必須擴展自 Thread 類,使自己成爲它的子類。
(2)線程的處理必須編寫在 run()方法內。


2.多線程的定義語法
class 類名稱 extends Thread // 從 Thread 類擴展出子類
{
屬性
方法…
修飾符 run(){ // 複寫 Thread 類裏的 run()方法
以線程處理的程序;
}
}


3. 要啓動線程必須調用 Thread類之中的 start()方法,而調用了 start()方法,也就是調用了 run()方法。


4. Java 中如果一個類繼承了某一個類,同時又想採用多線程技術的時, 就不能用 Thread 類產生線程, 因爲 Java 不允許多繼承, 這時就要用 Runnable接口來創建線程了。


5.多線程的定義語法
class 類名稱 implements Runnable // 實現 Runnable 接口
{
屬性
方法…
修飾符 run(){ // 複寫 Thread 類裏的 run()方法以線程處理的程序;
 }
}


6.實現 Runnable 接口相對於繼承 Thread 類來說,有如下顯著的優勢:
(1) 適合多個相同程序代碼的線程去處理同一資源的情況,把虛擬 CPU(線程)同程序的代碼、數據有效分離,較好地體現了面向對象的設計思想。
(2)可以避免由於 Java 的單繼承特性帶來的侷限。 開發中經常碰到這樣一種
情況,即:當要將已經繼承了某一個類的子類放入多線程中,由於一個類不能同時有兩個父類,所以不能用繼承 Thread 類的方式,那麼就只能採用實現 Runnable 接口的方式了。
(3)增強了程序的健壯性, 代碼能夠被多個線程共享, 代碼與數據是獨立的。
當多個線程的執行代碼來自同一個類的實例時,即稱它們共享相同的代碼。多個線程可以操作相同的數據,與它們的代碼無關。當共享訪問相同的對象時,即共享相同的數據。當線程被構造時,需要的代碼和數據通過一個對象作爲構造函數實參傳遞進去,這個對象就是一個實現了Runnable 接口的類的實例。
事實上,幾乎所有多線程應用都可用第二種方式,即實現 Runnable 接口。


7.任何線程一般具有五種狀態,即創建、就緒、運行、阻塞、終止。
   (1)新建狀態
在程序中用構造方法創建了一個線程對象後,新的線程對象便處於新建狀態,此
時,它已經有了相應的內存空間和其它資源,但還處於不可運行狀態。新建一個線程對象可採用線程構造方法來實現。
例如: Thread thread=new Thread();
    (2)就緒狀態
新建線程對象後,調用該線程的 start()方法就可以啓動線程。當線程啓動時,線
程進入就緒狀態。此時,線程將進入線程隊列排隊,等待 CPU 服務,這表明它已經具備了運行條件。
    (3)運行狀態
當就緒狀態的線程被調用並獲得處理器資源時,線程就進入了運行狀態。此時,
自動調用該線程對象的 run()方法。run()方法定義了該線程的操作和功能。
     (4)堵塞狀態
一個正在執行的線程在某些特殊情況下,如被人爲掛起或需要執行耗時的輸入輸
出操作時,將讓出 CPU 並暫時中止自己的執行,進入堵塞狀態。在可執行狀態下,如果調用 sleep()、suspend()、wait()等方法,線程都將進入堵塞狀態。堵塞時,線程不能進入排隊隊列,只有當引起堵塞的原因被消除後,線程纔可以轉入就緒狀態。
     (5)死亡狀態
線程調用 stop()方法時或 run()方法執行結束後,線程即處於死亡狀態。處於死亡狀態的線程不具有繼續運行的能力。


8.Thread 類中的主要方法
方法名稱                            方法說明
public static int activeCount()  返回線程組中目前活動的線程的數目
public static native Thread currentThread()  返回目前正在執行的線程
public void destroy()  銷燬線程
public static int enumerate(Thread tarray[]) 將當前和子線程組中的活動線程拷貝至指定的線程數組
public final String getName()  返回線程的名稱
public final int getPriority()  返回線程的優先級
public final ThreadGroup getThreadGroup()  返回線程的線程組
public static boolean interrupted()   判斷目前線程是否被中斷,如果是,返
回 true,否則返回 false
public final native boolean isAlive()判斷線程是否在活動,如果是,返回
true,否則返回 false
public boolean isInterrupted()  判斷目前線程是否被中斷,如果是,返
回 true,否則返回 false
public final void join() throws InterruptedException 等待線程死亡
public final synchronized void join(long millis)throws InterruptedException
等待 millis 毫秒後,線程死亡
public final synchronized void join(long
millis,int nanos) throws InterruptedException 等待 millis 毫秒加上 nanos 微秒後,線程死亡
public void run()   執行線程
public final void setName()  設定線程名稱
public final void setPriority(int newPriority) 設定線程的優先值
public static native void sleep(long millis)
throws InterruptedException
使目前正在執行的線程休眠 millis 毫秒
public static void sleep(long millis,int nanos)throws InterruptedException 使目前正在執行的線程休眠 millis 毫秒加上 nanos 微秒 
public native synchronized void start()  開始執行線程
public String toString()  返回代表線程的字符串
public static native void yield()將目前正在執行的線程暫停,允許其它
線程執行。


9.如果某個線程對象在啓動(調用 start()方法)之前調用了 setDaemon(true)方法,這個線程就變成了後臺線程。


10.Thread.sleep()方法迫使線程執行到該處後暫停執行,讓出 CPU 給別
的線程,在指定的時間(這裏是毫秒)後,CPU 回到剛纔暫停的線程上執行。


11.線程同步:當一個線程運行到 if(tickets>0)後, CPU 不去執行其它線程中的、 可能影響當前線程中的下一句代碼的執行結果的代碼塊,必須等到下一句執行完後才能去執行其它線程中的有關代碼塊。這段代碼就好比一座獨木橋,任何時刻,都只能有一個人在橋上行走,程序中不能有多個線程同時在這兩句代碼之間執行,這就是線程同步。


12.同步代碼塊定義語法

synchronized(對象)
{
需要同步的代碼 ;
}



13.除了可以對代碼塊進行同步外,也可以對函數實現同步,只要在需要同步的函數定義前加上 synchronized 關鍵字即可。
    同步方法定義語法:
訪問控制符 synchronized 返回值類型 方法名稱(參數)
{
....;
}


14.一旦有多個進程, 且它們都要爭用對多個鎖的獨佔訪問, 那麼就有可能發生死鎖。如果有一組進程或線程,其中每個都在等待一個只有其它進程或線程纔可以執行的操作,那麼就稱它們被死鎖了。


15.要避免死鎖, 應該確保在獲取多個鎖時, 在所有的線程中都以相同的順序獲取鎖.


16.線程間通訊
(1)這就是資源不同步的與原因,可以在 P 類中增加兩個同步方法:set()和 get();
(2) Java 是通過 Object 類的 wait、 notify、 notifyAll
這幾個方法來實現線程間的通信的,又因爲所有的類都是從 Object 繼承的,所以任何類都可以直接使用這些方法。下面是這三個方法的簡要說明:
wait:告訴當前線程放棄監視器並進入睡眠狀態,直到其它線程進入同一監視器
並調用 notify 爲止。
notify:喚醒同一對象監視器中調用 wait 的第一個線程。類似排隊買票,一個人
買完之後,後面的人可以繼續買。
notifyAll:喚醒同一對象監視器中調用 wait 的所有線程,具有最高優先級的線程首先被喚醒並執行。
(3)wait、notify、notifyAll 這三個方法只能在 synchronized 方法中調用,即無論線程調用一個對象的 wait 還是 notify 方法, 該線程必須先得到該對象的鎖標記, 這樣, notify只能喚醒同一對象監視器中調用 wait 的線程,使用多個對象監視器,就可以分別有多個 wait、notify 的情況,同組裏的 wait 只能被同組的 notify 喚醒。


17.
1、 線程(thread)是指程序的運行流程。 “多線程”的機制可以同時運行多個程序塊,使程序運行的效率更高,也解決了傳統程序設計語言所無法解決的問題。


2、 如果在類裏要激活線程,必須先做好下面兩項準備:
(1) 此類必須是擴展自 Thread 類,使自己成爲它的子類。
(2) 線程的處理必須編寫在 run()方法內。


3、 run()方法是定義在 Thread 類裏的一個方法,因此把線程的程序代碼編寫在 run()方法內,所做的就是覆蓋的操作。


4、 Runnable 接口裏聲明瞭抽象的 run()方法,因此必須在實現 Runnable 接口的類裏明確定義 run()方法。


5、 每一個線程,在其創建和消亡之前,均會處於下列五種狀態之一:創建、就緒、
運行、阻塞、終止。


6、 暫停狀態的線程可由下列的情況所產生:
(1)該線程調用對象的 wait()時。
(2)該線程本身調用 sleep()時。
(3)該線程和另一個線程 join()在一起時。


7、 被凍結因素消失的原因有:
(1) 如果線程是由調用對象的 wait()方法所凍結, 則該對象的 notify()方法被調用時可解除凍結。


(2)線程進入休眠(sleep)狀態,但指定的休眠時間到了。


8、 當線程的 run()方法運行結束,或是由線程調用它的 stop()方法時,則線程進入消亡狀態。


9、 Thread 類裏的 sleep()方法可用來控制線程的休眠狀態,休眠的時間要視 sleep()裏的參數而定。


10、要強制某一線程運行,可用 join()方法。


11、join()方法會拋出 InterruptedException 的異常,所以編寫時必須把 join()方法編寫在 try-catch 塊內。


12、當多個線程對象操縱同一共享資源時,要使用 synchronized 關鍵字來進行資源的同步處理。
  
發佈了29 篇原創文章 · 獲贊 17 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章