今天,我們開始Java高併發與多線程的第三篇,線程的基本屬性和主要方法。
【屬性】
- 編號(ID)
類型long
用於標識不同的線程,編號唯一,只存在java虛擬機的一次運行
- 名稱(Name)
類型String
可以不設置,默認值爲Thread-線程編號
- 線程類別(Daemon)
類型boolean
主要用於區分用戶線程和守護線程
值爲true表示該線程爲守護線程,否則爲用戶線程
默認值與相應線程的父線程該屬性值相同,該屬性必須在線程啓動前設置!否則會報錯
-
- 用戶線程
用戶行爲運行的線程;
一個Java虛擬機,必須等待所有的用戶線程結束之後纔可以停止運行。
-
- 守護線程
通常用於執行一些重要性不是很高的任務,比如監控資源等;
守護線程不會影響Java虛擬機的正常停止。
- 優先級(Priority)
類型int
該屬性是給線程調度器的提示,用於表示應用程序那個線程優先運行,但是並不保證真實的線程執行順序。
java定義了1~10的10個優先級別。默認值爲5(普通優先級別)。
對應一個具體的線程而言,優先級別的默認值與父線程相同。
注:在JVM中,使用-Xss參數來控制每個線程分配的內存大小,默認JDK1.4中是256K,JDK1.5+中是1M. |
【常用方法】
- public static native Thread currentThread()
返回當前線程,當前代碼的執行線程
- public long getId()
此方法返回線程的唯一標識,是一個long型的正數,在線程創建的時候被賦值。
- public final native boolean isAlive()
isAlive方法用於判斷當前線程是否處於活動狀態。
什麼是活動狀態呢?
活動狀態就是已經啓動尚未終止的,線程處於正在運行或者準備開始運行的狀態就認爲線程是"活動"的。
(新建狀態的線程isAlive()返回的是false)
- public synchronized void start()
啓動線程
- public void run()
線程的實際執行方法
- public void interrupt ()
interrupt() 中斷線程 由運行狀態到死亡狀態。
在Core Java中有這樣一句話:"沒有任何語言方面的需求要求一個被中斷的程序應該終止。中斷一個線程只是爲了引起該線程的注意,被中斷線程可以決定如何應對中斷 "。
中斷線程操作實質上是修改了一下中斷標示位爲true
當前線程正在運行,僅僅修改標示位,不再做其他的事
當前線程正在阻塞,修改標識位,如果是join,sleep,yield,則會拋出Interrup異常,修改標示位爲false
- public static boolean interrupted()
測試當前線程是否已經是中斷狀態,執行後具有清除中斷狀態功能。
- public boolean isInterrupted()
測試線程 Thread 對象是否已經是中斷狀態,但不清除中斷狀態標誌。
- public static native void yield()
此方法的作用是放棄當前的CPU資源,將它讓給其他的任務去佔用CPU的時間。但是放棄的時間不確定,有可能剛剛放棄就馬上獲得CPU時間片。
sleep 方法使當前運行中的線程睡眠一段時間,進入超時等待狀態,這段時間的長短是由程序設定的,yield方法使當前線程讓出CPU佔有權,但讓出的時間是不可設定的。
yield()不會釋放鎖標誌。
yield()只是使當前線程重新回到可運行狀態,所以執行yield()的線程有可能在進入到可執行狀態後馬上又被執行。
yield()只能使同優先級或更高優先級的線程有執行的機會。
- public static native void sleep(long millis) throws InterruptedException
sleep 導致當前線程休眠;
與 wait 方法不同的是 sleep 不會釋放當前佔有的鎖
sleep(long)會導致線程進入 TIMED-WATING狀態,而 wait()方法會導致當前線程進入 WATING狀態
可以拋出中斷異常
Thread.sleep(0)
由於Java採用搶佔式的線程調度算法,因此可能會出現某條線程常常獲取到CPU控制權的情況,爲了讓某些優先級比較低的線程也能獲取到CPU控制權,可以使用Thread.sleep(0)手動觸發一次操作系統分配時間片的操作,這也是平衡CPU控制權的一種操作。
- void join()
等待相應線程結束,若線程A調用B的join方法,那麼線程A會被暫停,直到線程B運行結束。
join方法中如果傳入參數,則表示這樣的意思:如果A線程中掉用B線程的join(10),則表示A線程會等待B線程執行10毫秒,10毫秒過後,A、B線程並行執行。
join(0)等價於join()。
- public final void setPriority(int newPriority)
設置線程優先級
- public final void setDaemon(booleanon)
將線程設置爲守護線程
- public static int activeCount()
程序中活躍的線程數
- public static native boolean holdsLock(Object obj)
當前線程是否擁有某個具體對象的鎖。
- @Deprecated
public final void stop()
強制停止,已廢棄
可能釋放鎖導致數據不對。
可能導致清理工作做不好。
- suspend和resume
暫停和恢復
同上,已廢棄。
- public final native void wait (longtimeout)
繼承object
調用該方法的線程進入 WAITING 狀態,只有等待另外線程的通知或被中斷纔會返回,需要注意的
是調用 wait()方法後,會釋放對象的鎖。
因此,wait 方法一般用在同步方法或同步代碼塊中。
- public final native void notify()
繼承自object
喚醒在此對象監視器上等待的單個線程,如果所有線程都在此對象上等待,則會選擇喚醒其中一個線程,選擇是任意的,並在對實現做出決定時發生,線程通過調用其中一個wait() 方法,在對象的監視器上等待,直到當前的線程放棄此對象上的鎖定,才能繼續執行被喚醒的線程,被喚醒的線程將以常規方式與在該對象上主動同步的其他所有線程進行競爭。
但是要注意,notify不釋放鎖。
類似的方法還有 notifyAll() ,喚醒再次監視器上等待的所有線程。
- public final native void notifyAll()
把該對象等待隊列裏面的所有線程喚醒,成爲可運行線程。
本篇比較短,但是因爲容易被遺漏掉,所以單獨拿出來講,下一篇咱們講多線程裏面的重頭戲------鎖。