Java yield()線程讓步實(shí)現(xiàn)過程解析
一、yield()介紹
yield()的作用是讓步。它能讓當(dāng)前線程由“運(yùn)行狀態(tài)”進(jìn)入到“就緒狀態(tài)”,從而讓其它具有相同優(yōu)先級(jí)的等待線程獲取執(zhí)行權(quán);但是,并不能保證在當(dāng)前線程調(diào)用yield()之后,其它具有相同優(yōu)先級(jí)的線程就一定能獲得執(zhí)行權(quán);也有可能是當(dāng)前線程又進(jìn)入到“運(yùn)行狀態(tài)”繼續(xù)運(yùn)行!
二、yield()示例
下面,通過示例查看它的用法。
package com.demo.Thread; public class Thread1 extends Thread{ public Thread1(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); // i整除4時(shí),調(diào)用yield if (i%4 == 0){ Thread.yield(); } } } }
package com.demo.Thread; public class YieldTest { public static void main(String[] args){ Thread1 t1 = new Thread1("t1"); Thread1 t2 = new Thread1("t2"); t1.start(); t2.start(); } }
(某一次的)運(yùn)行結(jié)果:
t1 [5]:0 t2 [5]:0 t1 [5]:1 t1 [5]:2 t1 [5]:3 t1 [5]:4 t1 [5]:5 t1 [5]:6 t1 [5]:7 t1 [5]:8 t1 [5]:9 t2 [5]:1 t2 [5]:2 t2 [5]:3 t2 [5]:4 t2 [5]:5 t2 [5]:6 t2 [5]:7 t2 [5]:8 t2 [5]:9
結(jié)果說明:
“線程t1”在能被4整數(shù)的時(shí)候,并沒有切換到“線程t2”。這表明,yield()雖然可以讓線程由“運(yùn)行狀態(tài)”進(jìn)入到“就緒狀態(tài)”;但是,它不一定會(huì)讓其它線程獲取CPU執(zhí)行權(quán)(即,其它線程進(jìn)入到“運(yùn)行狀態(tài)”),即使這個(gè)“其它線程”與當(dāng)前調(diào)用yield()的線程具有相同的優(yōu)先級(jí)。
三、yield() 與 wait()的比較
我們知道,wait()的作用是讓當(dāng)前線程由“運(yùn)行狀態(tài)”進(jìn)入“等待(阻塞)狀態(tài)”的同時(shí),也會(huì)釋放同步鎖。而yield()的作用是讓步,它也會(huì)讓當(dāng)前線程離開“運(yùn)行狀態(tài)”。它們的區(qū)別是:
(01) wait()是讓線程由“運(yùn)行狀態(tài)”進(jìn)入到“等待(阻塞)狀態(tài)”,而yield()是讓線程由“運(yùn)行狀態(tài)”進(jìn)入到“就緒狀態(tài)”。
(02) wait()是會(huì)讓線程釋放它所持有對(duì)象的同步鎖,而yield()方法不會(huì)釋放鎖。
下面通過示例演示yield()是不會(huì)釋放鎖的。
package com.demo.Thread; public class YieldLockTest { private static Object obj = new Object(); public static void main(String[] args){ ThreadA t1 = new ThreadA("t1"); ThreadA t2 = new ThreadA("t2"); t1.start(); t2.start(); } static class ThreadA extends Thread{ public ThreadA(String name){ super(name); } public void run(){ //獲取obj對(duì)象的同步鎖 synchronized(obj){ for(int i=0; i <10; i++){ System.out.printf("%s [%d]:%d\n", this.getName(), this.getPriority(), i); // i整除4時(shí),調(diào)用yield if (i%4 == 0){ Thread.yield(); } } } } } }
(某一次)運(yùn)行結(jié)果:
t1 [5]:0 t1 [5]:1 t1 [5]:2 t1 [5]:3 t1 [5]:4 t1 [5]:5 t1 [5]:6 t1 [5]:7 t1 [5]:8 t1 [5]:9 t2 [5]:0 t2 [5]:1 t2 [5]:2 t2 [5]:3 t2 [5]:4 t2 [5]:5 t2 [5]:6 t2 [5]:7 t2 [5]:8 t2 [5]:9
結(jié)果說明:
主線程main中啟動(dòng)了兩個(gè)線程t1和t2。t1和t2在run()會(huì)引用同一個(gè)對(duì)象的同步鎖,即synchronized(obj)。在t1運(yùn)行過程中,雖然它會(huì)調(diào)用Thread.yield();但是,t2是不會(huì)獲取cpu執(zhí)行權(quán)的。因?yàn)?,t1并沒有釋放“obj所持有的同步鎖”!
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Intellij Idea新建SpringBoot項(xiàng)目方式
這篇文章主要介紹了Intellij Idea新建SpringBoot項(xiàng)目方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-09-09SpringCloud Open feign 使用okhttp 優(yōu)化詳解
這篇文章主要介紹了SpringCloud Open feign 使用okhttp 優(yōu)化詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2021-02-02springboot與數(shù)據(jù)庫返回?cái)?shù)據(jù)中文亂碼
大家好,本篇文章主要講的是springboot與數(shù)據(jù)庫返回?cái)?shù)據(jù)中文亂碼,感興趣的同學(xué)趕快來看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽2022-01-01Java復(fù)制(拷貝)數(shù)組的4種方法:arraycopy()方法、clone() 方法、copyOf()和copyOfRa
這篇文章主要介紹了Java復(fù)制(拷貝)數(shù)組的4種方法:arraycopy()方法、clone() 方法、copyOf()和copyOfRan,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01Java異常詳解_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
異常是Java語言中的一部分,它代表程序中由各種原因引起的“不正常”因素。下面通過本文給大家介紹java異常的相關(guān)知識(shí),感興趣的朋友一起看看吧2017-06-06Java Web實(shí)現(xiàn)文件下載和亂碼處理方法
文件上傳和下載是web開發(fā)中常遇到的問題。今天小編給大家分享下Java Web實(shí)現(xiàn)文件下載和亂碼處理方法的相關(guān)資料,需要的朋友可以參考下2016-10-10Java實(shí)戰(zhàn)之實(shí)現(xiàn)一個(gè)好用的MybatisPlus代碼生成器
這篇文章主要介紹了Java實(shí)戰(zhàn)之實(shí)現(xiàn)一個(gè)好用的MybatisPlus代碼生成器,文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)java的小伙伴們有非常好的幫助,需要的朋友可以參考下2021-04-04