Thread常用方法
join
當(dāng)某個(gè)程序執(zhí)行流中調(diào)用其他線程的join()方法時(shí),調(diào)用線程將被阻塞,直到被join()方法加入的join線程執(zhí)行完為止。
void join()
等待該線程終止。
void join(long millis)
等待該線程終止的時(shí)間最長為 millis 毫秒。
void join(long millis, int nanos)
等待該線程終止的時(shí)間最長為 millis 毫秒 + nanos 納秒。
public class Test {
public static void main(String[] args) {
Thread thread = new MyRunner3();
thread.start();
try {
//主線程等待thread的業(yè)務(wù)處理完了之后再向下運(yùn)行
//thread和主線程合并了
//Thread要先啟動(dòng)在join
thread.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for(int i = 0; i < 100; i++){
System.out.println("main : " + i);
}
}
}
class MyRunner3 extends Thread {
@Override
public void run() {
for(int i = 0; i < 5; i++){
System.out.println("i am " + getName());
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Join()是通過wait函數(shù)實(shí)現(xiàn)的主線程阻塞。
//源碼
public final void join() throws InterruptedException {
join(0);
}
public final synchronized void join(long millis) throws InterruptedException {
long base = System.currentTimeMillis();
long now = 0;
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (millis == 0) {
while (isAlive()) {
wait(0);
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
sleep
Sleep(long)讓出cpu的使用權(quán),不釋放鎖 Wait(long)讓出cpu使用權(quán),并釋放鎖。
static void sleep(long millis)
在指定的毫秒數(shù)內(nèi)讓當(dāng)前正在執(zhí)行的線程休眠(暫停執(zhí)行),此操作受到系統(tǒng)計(jì)時(shí)器和調(diào)度程序精度和準(zhǔn)確性的影響。
static void sleep(long millis, int nanos)
在指定的毫秒數(shù)加指定的納秒數(shù)內(nèi)讓當(dāng)前正在執(zhí)行的線程休眠(暫停執(zhí)行),此操作受到系統(tǒng)計(jì)時(shí)器和調(diào)度程序精度和準(zhǔn)確性的影響。
public class TestThread {
final static Object syn = new Object();
public static void main(String[] args) {
// TODO Auto-generated method stub
new Thread(){
public void run() {
System.out.println(getName()+"等待獲取鎖。。。。。。。。。。。");
synchronized (syn) {
System.out.println(getName()+"獲取到鎖。。。。。。。。。。。");
System.out.println(getName()+"進(jìn)入睡眠狀態(tài)。。。。。。。。。。。");
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(getName()+"睡眠完畢。。。。。。。。。。。");
}
}
}.start();
new Thread(){
public void run() {
System.out.println(getName()+"等待獲取鎖。。。。。。。。。。。");
long time = System.currentTimeMillis();
synchronized (syn) {
System.out.println(getName()+"獲取到鎖,已過去"+(System.currentTimeMillis()-time)+"。。。。。。。。。。。");
System.out.println(getName()+"Do Somethings。。。。。。。。。。。");
}
}
}.start();
}
}
//---------輸出-------------------------------
Thread-0等待獲取鎖。。。。。。。。。。。
Thread-0獲取到鎖。。。。。。。。。。。
Thread-0進(jìn)入睡眠狀態(tài)。。。。。。。。。。。
Thread-1等待獲取鎖。。。。。。。。。。。
Thread-0睡眠完畢。。。。。。。。。。。
Thread-1獲取到鎖,已過去10001。。。。。。。。。。。
Thread-1Do Somethings。。。。。。。。。。。
yield-線程讓步
yield()方法和sleep()方法有點(diǎn)相似,它也是Thread類提供的一個(gè)靜態(tài)方法,它也可以讓當(dāng)前正在執(zhí)行的線程暫停,但它不會(huì)阻塞該線程,它只是將該線程轉(zhuǎn)入到就緒狀態(tài)。即讓當(dāng)前線程暫停一下,讓系統(tǒng)的線程調(diào)度器重新調(diào)度一次,完全可能的情況是:當(dāng)某個(gè)線程調(diào)用了yield()方法暫停之后,線程調(diào)度器又將其調(diào)度出來重新執(zhí)行。
實(shí)際上,當(dāng)某個(gè)線程調(diào)用了yield()方法之后,只有優(yōu)先級(jí)與當(dāng)前線程相同或者比當(dāng)前線程更高的處于就緒狀態(tài)的線程才會(huì)獲得執(zhí)行機(jī)會(huì)。
sleep()與yield()方法區(qū)別:
- sleep()方法暫停當(dāng)前線程后,會(huì)給其他線程執(zhí)行機(jī)會(huì),不會(huì)理會(huì)其他線程的優(yōu)先級(jí);但yield()方法只會(huì)給優(yōu)先級(jí)高或者相同的線程機(jī)會(huì)
- sleep()方法會(huì)將線程轉(zhuǎn)入到阻塞狀態(tài),知道經(jīng)過阻塞時(shí)間才會(huì)轉(zhuǎn)入就緒狀態(tài);而yield()不會(huì)將線程轉(zhuǎn)入阻塞狀態(tài),它只是強(qiáng)制當(dāng)前線程進(jìn)入就緒狀態(tài)。因此完全有可能某個(gè)線程調(diào)用了yield()方法暫停之后,立即再次獲取處理器資源被執(zhí)行。
- sleep()方法聲明拋出InterruptedException異常,所以嗲用sleep()方法時(shí)要么捕捉該異常,要么顯示聲明拋出該異常;而yield()方法則沒有聲明拋出任何異常。
- sleep()方法比yield()方法更好的可移植性,通常不建議使用yield()方法來控制并發(fā)線程執(zhí)行。
currentThread
static Thread currentThread()
返回對(duì)當(dāng)前正在執(zhí)行的線程對(duì)象的引用。
優(yōu)先級(jí)
線程的優(yōu)先級(jí)用數(shù)字表示,范圍從1到10,默認(rèn)的是為5
每個(gè)線程默認(rèn)的優(yōu)先級(jí)與創(chuàng)建它的父線程的優(yōu)先級(jí)相同
優(yōu)先級(jí)越高的線程,被執(zhí)行的順序就比較靠前,
在Thread中存在三個(gè)常量:
MAX_PRIORITY
MIN_PRIORITY
NORM_PRIORITY
int getPriority()
返回線程的優(yōu)先級(jí)。
void setPriority(int newPriority)
更改線程的優(yōu)先級(jí)。
守護(hù)線程
在B線程中調(diào)用A.setDaemon(true),將A設(shè)置為B線程的守護(hù)線程,A線程隨B線程的消亡而消亡
void setDaemon(boolean on)
將該線程標(biāo)記為守護(hù)線程或用戶線程。