1 yield()介紹
yield()的作用是讓步,他能讓當前線程由"運行狀態"到"就緒狀態",從而讓其他具有相同相同優先級的等待線程獲取執行權,但是,並不能保證在當前線程調用yield()之後,其他具有相同優先級的線程就一定能獲得執行權,也有可能又進入到"運行狀態"繼續運行"
2yield()示例
package com.tuhu.filt.javadatayield;
public class ThreadA extends Thread {
public ThreadA(String name){
super(name);
}
public synchronized void run(){
for(int i =0;i<10;i++){
System.out.printf("%s [%d]:%d\n", this.getName(), this.getPriority(), i);
if(i % 4 == 0){
Thread.yield();
}
}
}
}
class YieldTest{
public static void main(String[] args) {
ThreadA t1 = new ThreadA("t1");
ThreadA t2 = new ThreadA("t2");
t1.start();
t2.start();
}
}
我們可以看到在t2爲0可以被4整除的時候,並沒有切換到線程t1,這表明yield()雖然可以讓線程由"運行狀態轉爲就緒狀態",但是它不一定會讓其他線程獲取CPU執行權(即,其他線程進入到"運行狀態")即使這個"其他線程"與當前調用yield()的線程具有相同的優先級。
yield()與wait()的比較
我們知道wait()的作用是讓當前線程由"運行狀態"進入"等待(阻塞)狀態"的同時,也會釋放同步鎖,而yield()的作用是讓步,它也會讓當前線程離開"運行狀態"。他們的區別是
01 wait是會讓線程由運行狀態進入到等待(阻塞)狀態的,而yield是讓線程由運行狀態進入到就緒狀態
02 wait()是會讓線程釋放它所持有對象的同步鎖,而yield()方法不會釋放鎖
下面通過示例演示yield()是不會釋放鎖的
package com.tuhu.filt.javadatayield;
public class YieldLockTest {
private static Object obj = new Object();
public static void main(String[] args) {
ThreadB t1 = new ThreadB("t1");
ThreadB t2 = new ThreadB("t2");
t1.start();
t2.start();
}
static class ThreadB extends Thread{
public ThreadB(String name){
super(name);
}
public void run(){
synchronized (obj){
for(int i = 0;i<10;i++){
System.out.printf("%s [%d]:%d\n", this.getName(), this.getPriority(), i);
// i整除4時,調用yield
if (i%4 == 0)
Thread.yield();
}
}
}
}
}
結果‘
可以看到上面代碼線程對象是兩個,但是有同步鎖的卻是類的對象,所以兩個線程拿來拿去拿的都是這個類的同步鎖,而且根據yield線程讓步不會釋放同步鎖來看,結果完全符合這個特性,t1拿到同步鎖之後就沒釋放,一直等到t1執行完纔給了t2。