標籤:span 資料 isalive 進程 耦合 二次 有用 自動 程式
//作業系統可以產生多個進程,每個進程也可以產生多個線程
1.線程
//"主線程”是main線程
//線程有4種狀態:建立、運行、中斷、死亡
(1)建立:
①通過繼承Thread類建立:
需要重寫Thread類的run()方法;
//優點:可以在子類中增加新的成員變數和方法,使線程具有某種屬性和功能。
缺點:Java不支援多繼承,Thread類的子類不能再擴充其他的類。
②通過實現Runnable介面建立:
構造方法:Thread(Runnable target)
//優點:對於使用同一目標對象的線程,目標對象的成員變數是這些線程共用的資料單元;
建立目標對象的類在必要時可以是某個特定類的子類。
因此使用Runnable介面比使用Thread的子類更具有靈活性。
中斷原因:
①JVM將CPU資源從當前線程切換給其他線程,使本線程讓出CPU的使用權處於中斷狀態。
②線程使用CPU資源期間,執行了sleep(int millsecond)方法,使當前線程進入休眠狀態。
③線程使用CPU資源期間,執行了wait()方法,使得當前線程進入等待狀態。
④線程使用CPU資源期間,執行某個操作進入阻塞狀態,比如執行讀/寫操作引起阻塞。
死亡(線程釋放了實體和線程對象的記憶體)原因:
①執行完run()方法中的全部語句,結束了run()方法。
②線程被提前強制性地終止,即強制run()方法結束。
目標對象與線程的關係:
①完全解耦:目標對象沒有組合線程對象。
②弱耦合:目標對象可以組合線程,即將線程作為自己的成員(在Thread子類或實現Runnable的類中建立線程)。
//在實際問題中,根據實際情況確定目標對象和線程是組合或完全解耦關係,兩種關係各有優缺點。
線程的常用方法:
1.start() throws IllegalThreadStateException
啟動線程,二次調用start()方法會導致異常;
2.run()
定義線程對象被調度之後所執行的操作,系統自動調用而使用者程式不得引用;
3.sleep(int millsecond) throws InterruptedException
參數millsecond是以毫秒為單位的休眠時間,如果線程在休眠時被打斷,JVM就拋出異常;
4.isAlive()
判斷線程是否存在(非建立和死亡狀態);
5.currentThread()
返回當前正在使用CPU資源的線程;
6.interrupt()
"吵醒"休眠的線程,導致休眠的線程發生InterruptedException異常;
2.線程同步(用synchronized修飾)
線程同步機制:當一個線程A使用synchronized方法時,其他線程想使用這個synchronized方法時就必須等待,直到線程A使用完該synchronized方法。
同步方法中的方法(都是Object類的final方法):
1.wait()
中斷線程的執行,使本線程等待,暫時讓出CPU的使用權;
2.notify()
通知處於等待中的某一個線程結束等待;
3.notifyAll()
通知所有由於使用這個同步方法而處於等待的線程結束等待,曾中斷的線程從剛才的中斷處繼續執行這個同步方法;
//不可以在非同步方法中使用上述的三個方法
//遵循"先中斷先繼續”的原則
3.線程聯合
一個線程A在佔有CPU資源期間,可以讓其他線程調用join()方法和本線程聯合,如:B.join();
如果線程A在佔有CPU資源期間一旦聯合B線程,那麼A線程將立刻中斷執行,一直等到它聯合的B線程執行完畢,A線程再重新排隊等待CPU資源,以便恢複執行。
//如果A準備聯合的B線程已經結束,那麼B.join()不會產生任何效果。
4.GUI線程
當Java程式包含GUI時,JVM在運行程式時會自動啟動更多的線程,其中兩個重要的線程:AWT-EventQuecue和AWT-Windows
當觸發ActionEvent事件時,AWT-EventQuecue線程就立刻等候執行處理事件的代碼。
5.計時器線程
javax.swing.Timer類(避免與java.util.Timer類混淆):
構造方法:
Timer(int a)
必須調用addActionListener(ActionListener listener)方法獲得監視器(必須是組件類);
Timer(int a,Object b)
參數a的單位是毫秒,確定計時器每隔a毫秒"響鈴"一次,參數b是計時器的監視器;
常用方法:
1.setReapeats(boolean b)
只想計時器響鈴一次,可以調用此方法,參數b取值false;
2.setInitialDelay(int depay)
設定首次響鈴的延時,預設延時為a;
3.start()
啟動計時器;
4.stop()
停止計時器,即掛起線程;
5.restart()
重新啟動計時器,即恢複線程;
6.守護線程
線程預設是非守護線程(使用者線程),一個線程調用void setDaemon(boolean on)方法將自己設定成一個守護線程,如:thread.setDaemon(true);
當所有使用者線程結束運行時, 即使守護線程的run方法還未執行完,也立刻結束運行。
//守護線程用來做一些不是很嚴格的工作
Java多線程機制