Thread.yield()和Thread.sleep(0)
關(guān)于Thread.yield()和Thread.sleep(0)的語義問題真是一個(gè)讓人撓頭的問題,翻了好多資料,在java6語言規(guī)范中看到了一段這樣的描述:
重點(diǎn)在紅框中,簡而言之就是:sleep(0)和yield()的實(shí)現(xiàn)不需要任何可見的效果。那么在實(shí)現(xiàn)這兩個(gè)函數(shù)的語義時(shí)就可以什么都不做,這取決于具體的JVM實(shí)現(xiàn)。后來再看java8的語言規(guī)范時(shí)發(fā)現(xiàn)紅框內(nèi)的提示被去掉了,官方給出了下面的解釋:
大致意思就是說之前的那句沒表達(dá)清楚,所以在語言規(guī)范中去掉了,最后強(qiáng)調(diào)的說了:java語言規(guī)范不希望yiled和spleep(0)具有很強(qiáng)的明確語義,可以不用實(shí)現(xiàn)他們。
后來又在**《java concurrency in practice》**的注釋中找到了這么一句(《java concurrency in practice》這本書是設(shè)計(jì)juc的幾個(gè)人寫的,可靠性是非常高的)
The semantics of Thread.yield and Thread.sleep(0) are undefined [JLS17.9]; the JVM is free to implement them as no-ops or treat them as scheduling hints. In particular, they are not required to have the semantics of sleep(0) on Unix systems — put the current thread at the end of the run queue for that priority, yielding to other threads of the same priority — though some JVMs implement yield in this way.
<-------------------------分割線哥哥------------------------------------------------------------------------>
翻譯:
java規(guī)范中并沒有定義Thread.yield和Thread.sleep(0)的語義。jvm可以自由的去實(shí)現(xiàn)他們,可以不做任何操作,也可以給系統(tǒng)調(diào)度器提示。特別說下,sleep(0)在Unix系統(tǒng)下的語義是:把線程放到運(yùn)行隊(duì)列的末尾,并且讓出執(zhí)行權(quán)給其他同優(yōu)先級(jí)的線程,很多的jvm也是這末實(shí)現(xiàn)的,但并不是要求必須這末實(shí)現(xiàn),你想怎么玩就怎么玩,沒人管你。
最后再來看下我們常用的hotspot中的具體實(shí)現(xiàn):上面這段代碼是hotspot的源碼,由于ConvertSleepToYield的默認(rèn)值為true,所以在hotspot中當(dāng)sleep(0)時(shí)效果相當(dāng)于yield()。會(huì)讓當(dāng)前線程放棄剩余時(shí)間片,進(jìn)入相同優(yōu)先級(jí)線程隊(duì)列的隊(duì)尾,只有排在前面的所有同優(yōu)先級(jí)線程完成調(diào)度后,它才能再次獲執(zhí)行的機(jī)會(huì)。
總結(jié)
結(jié)合java doc中這兩個(gè)函數(shù)的注解總結(jié)下:
Thread.yield()和Thread.sleep(0)語義實(shí)現(xiàn)取決于具體的jvm虛擬機(jī),某些jvm可能什么都不做,而大多數(shù)虛擬機(jī)會(huì)讓線程放棄剩余的cpu時(shí)間片,重新變?yōu)閞unnable狀態(tài),并放到同優(yōu)先級(jí)線程隊(duì)列的末尾等待cpu資源。 但是當(dāng)我們調(diào)用Thread.yield()的那一刻,并不意味著當(dāng)前線程立馬釋放cpu資源,這是因?yàn)楂@得時(shí)間片的線程從runable切換到running仍需要一定的準(zhǔn)備時(shí)間,這段時(shí)間當(dāng)前線程仍可能運(yùn)行一小段時(shí)間。
總結(jié)
以上是生活随笔為你收集整理的Thread.yield()和Thread.sleep(0)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 股票期货数据的resample处理
- 下一篇: 开源个小工具simple-repo