記錄Java Thread的基礎(chǔ)點欣簇。
線程的實現(xiàn)
線程的定義有兩種方式
- 繼承Thread類
- 實現(xiàn)Runnable接口
線程的啟動
無論是繼承Thread類還是實現(xiàn)Runnable接口探膊,線程的啟動方式都是:
Thread thread = new Thread();
thread.start();
// 或者
Thread runnable = new Thread(new Runnable());
runnable.start();
run()
線程實際運行調(diào)用的是run()方法倦畅。
- 其中Thread類中的run() 實際是調(diào)用傳入Runnable對象的run()方法
@Override
public void run() {
if (target != null) {
target.run();
}
}
線程狀態(tài)
NEW, // 新建邑狸,創(chuàng)建后尚未啟動的線程處于這種狀態(tài)
RUNNABLE, // 運行
// 處于這種狀態(tài)的線程有可能正在執(zhí)行也有可能正在等待CPU分配執(zhí)行時間
BLOCKED, // 阻塞
WAITING, // 無限期等待
// 處于這種狀態(tài)CPU不會分配執(zhí)行時間
// 需要其他線程喚醒
TIMED_WAITING, // 限期等待
// 處于這種狀態(tài)CPU不會分配執(zhí)行時間
// 不需要其他線程喚醒违孝,在一定時間之后會由系統(tǒng)自動喚醒
TERMINATED; // 結(jié)束泉坐,線程已經(jīng)結(jié)束執(zhí)行
線程狀態(tài)轉(zhuǎn)換關(guān)系圖:
線程的屬性和方法
設(shè)置優(yōu)先級
public final void setPriority(int newPriority)
每個類都有自己的優(yōu)先級两入,一般property用1-10的整數(shù)表示轨奄,默認(rèn)優(yōu)先級是5孟害,優(yōu)先級最高是10;優(yōu)先級高的線程并不一定比優(yōu)先級低的線程執(zhí)行的機會高挪拟,只是執(zhí)行的機率高挨务;默認(rèn)一個線程的優(yōu)先級和創(chuàng)建他的線程優(yōu)先級相同。
sleep
public static native void sleep(long millis) throws InterruptedException;
public static void sleep(long millis, int nanos) throws InterruptedException
可以使用TimeUnit的sleep方法
TimeUnit.MILLISECONDS.sleep(500L);
// 內(nèi)部實現(xiàn)還是調(diào)用Thread.sleep()實現(xiàn)的,源碼如下
public void sleep(long timeout) throws InterruptedException {
if (timeout > 0) {
long ms = toMillis(timeout);
int ns = excessNanos(timeout, ms);
Thread.sleep(ms, ns);
}
}
當(dāng)前線程睡眠/millis的時間(millis指定睡眠時間是其最小的不執(zhí)行時間舞丛,因為sleep(millis)休眠到達后耘子,無法保證會被JVM立即調(diào)度);sleep()是一個靜態(tài)方法(static method) 球切,所以他不會停止其他的線程也處于休眠狀態(tài)谷誓;線程sleep()時不會失去擁有的對象鎖。作用:保持對象鎖吨凑,讓出CPU捍歪,調(diào)用目的是不讓當(dāng)前線程獨自霸占該進程所獲取的CPU資源户辱,以留一定的時間給其他線程執(zhí)行的機會;
yield
public static native void yield();
讓出CPU的使用權(quán)糙臼,給其他線程執(zhí)行機會庐镐、讓同等優(yōu)先權(quán)的線程運行(但并不保證當(dāng)前線程會被JVM再次調(diào)度、使該線程重新進入Running狀態(tài))变逃,如果沒有同等優(yōu)先權(quán)的線程必逆,那么yield()方法將不會起作用。
它僅能是一個線程從運行狀態(tài)轉(zhuǎn)換到可運行狀態(tài)揽乱,而不是等待或阻塞狀態(tài)名眉。
join
public final void join() throws InterruptedException
public final synchronized void join(long mills)
throws InterruptedException
public final synchronized void join(long millis, int nanos) throws InterruptedException
使用該方法的線程會在此之間執(zhí)行完畢后再往下繼續(xù)執(zhí)行。
特殊的線程方法
object.wait()
// 存在對象
Object obj ;
// 使用
synchronized(obj){
obj.wait(); // 無限等待
obj.wait(1000L); // 設(shè)定等待超時時間(有限等待)
}
當(dāng)一個線程執(zhí)行到wait()方法時凰棉,他就進入到一個和該對象相關(guān)的等待池(Waiting Pool)中损拢,同時失去了對象的機鎖—暫時的,wait后還要返還對象鎖撒犀。當(dāng)前線程必須擁有當(dāng)前對象的鎖福压,如果當(dāng)前線程不是此鎖的擁有者,會拋出IllegalMonitorStateException異常,所以wait()必須在synchronized 代碼塊中調(diào)用或舞。
object.notify()/notifyAll()
喚醒在當(dāng)前對象等待池中等待的第一個線程/所有線程荆姆。notify()/notifyAll()也必須擁有相同對象鎖,否則也會拋出IllegalMonitorStateException異常映凳。