概念介紹
要讓當前正被 CPU 執(zhí)行的線程讓度出 CPU,其實有兩種方式。一種是被動的,比如當前線程需要進行 IO 操作;但是這里討論的是一種主動讓度的方式。而要達到主動的讓度一般就兩種方式,一種是 sleep 方法,一種是 yield 方法。(wait 方法是一種條件等待的方式,需要別的線程去喚醒,但是 wait 帶時間的方法,不需要條件,也是一種主動讓度的方式)。
讓度方法介紹
sleep 方法
它是聲明在 Thread 類中的一個靜態(tài)方法,入?yún)橐粋€毫秒單位的時間值。使用也非常簡單:
public static void main(String[] args) {
System.out.println("main start");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("main end");
}
可以看到 sleep 方法有一個中斷異常,因此當線程在 sleep 時,別的線程調(diào)用了該線程的 interrupt 方法后,該線程會響應(yīng)這個中斷,拋出異常。
還有兩點需要注意,sleep 方法和 wait 方法剛好相反,sleep 時不會釋放鎖,因此當前線程會一直占有鎖。還有一點是如果傳入的入?yún)樨摂?shù)則會拋出 IllegalArgumentException 異常。
yield 方法
它也是聲明在 Thread 類中的一個靜態(tài)方法,入?yún)榭眨划斠粋€線程調(diào)用該方法時,就是在告訴操作系統(tǒng)的線程調(diào)度器,請求讓度出自己占用的 CPU ,但是線程調(diào)度器是可以忽略這個請求的,因此有時候并不一定生效。
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
for (int i = 0 ; i < 10 ;i ++) {
if (i == 0) {
System.out.println("t"+i+" yield");
Thread.yield();
}
System.out.println("t"+i+" end");
}
});
Thread t2 = new Thread(() -> {
for (int i = 0 ; i < 10 ;i ++) {
if (i == 0) {
System.out.println("t"+i+" yield");
Thread.yield();
}
System.out.println("t"+i+" end");
}
});
t1.start();
t2.start();
System.out.println("main end");
}
以上代碼多次嘗試能看到 yield 方法執(zhí)行的效果,有時候能生效,有時候是不生效的。這個方法在實際工作中是不用的,所以只做一個了解就行。
總結(jié)
1、sleep 方法會響應(yīng)中斷,在等待時被中斷會拋出異常;
2、sleep 方法不會釋放鎖,因此執(zhí)行的時候當前線程還是占用鎖的;
3、yield 方法只是請求線程調(diào)度器,出讓自己的 CPU 執(zhí)行時間,但是不一定成功;
4、yield 方法在實際工作中是不使用的,了解就好。