Thread.yield()
(一)java yield()方法注釋:
/*** A hint to the scheduler that the current thread is willing to yield* its current use of a processor. The scheduler is free to ignore this* hint.** <p> Yield is a heuristic attempt to improve relative progression* between threads that would otherwise over-utilise a CPU. Its use* should be combined with detailed profiling and benchmarking to* ensure that it actually has the desired effect.** <p> It is rarely appropriate to use this method. It may be useful* for debugging or testing purposes, where it may help to reproduce* bugs due to race conditions. It may also be useful when designing* concurrency control constructs such as the ones in the* {@link java.util.concurrent.locks} package.*/大致意思:yield()方法會通知線程調(diào)度器放棄對處理器的占用,但調(diào)度器可以忽視這個通知。yield()方法主要是為了保障線程間調(diào)度的連續(xù)性,防止某個線程一直長時間占用cpu資源。但是他的使用應(yīng)該基于詳細(xì)的分析和測試。這個方法一般不推薦使用,它主要用于debug和測試程序,用來減少bug以及對于并發(fā)程序結(jié)構(gòu)的設(shè)計。
(二)方法理解:
Thread.yield()翻譯成中文就是讓步的意思,根據(jù)語義理解就是線程讓出當(dāng)前時間片給其他線程執(zhí)行。這個函數(shù)在JSL中未給出明確的語義,就是沒有要求具體如何實現(xiàn),這取決于各個不同jvm的具體實現(xiàn)。部分jvm在執(zhí)行這個函數(shù)時可能什么都不做,但是大部分jvm的實現(xiàn)都是:將線程從running狀態(tài)轉(zhuǎn)為runnable狀態(tài),然后放入同優(yōu)先級等待隊列的末尾,等待前面所有相同優(yōu)先級的線程調(diào)度完成后才可能再度獲得執(zhí)行機會。不過當(dāng)同優(yōu)先級隊列中剛好只剩這個線程時,那么這個線程可能很快就又獲得了cpu時間片。我們常用的HotSpot默認(rèn)采用的是第二種方式。
我們再看個小例子:
public class YieldTest extends Thread {public YieldTest(String name) {super(name);}@Overridepublic void run() {for (int i = 1; i <= 1000; i++) {System.out.println("" + this.getName() + "-----" + i);if (i == 30 || i == 100 || i == 500 || i == 700 || i == 800 || i == 900) {Thread.yield();}}}public static void main(String[] args) {YieldTest yt1 = new YieldTest("張三");YieldTest yt2 = new YieldTest("李四");yt1.start();yt2.start();} }運行結(jié)果:
我們會驚奇的發(fā)現(xiàn):調(diào)用Thread.yield()后線程并不一定會立刻停止執(zhí)行,i == 100時調(diào)用Thread.yield()后線程沒有立刻放棄cpu時間片,李四這個無恥之徒還在執(zhí)行呢!
這個主要是因為張三從runnable狀態(tài)切換到running狀態(tài)是需要一些準(zhǔn)備的,這個需要耗費一些時間。系統(tǒng)為了避免cpu資源的浪費還會讓李四在執(zhí)行一小段時間。不過調(diào)度器后面一定會讓張三執(zhí)行下的,面子工程必須得做的。所以就如同yield()方法注釋中說的,業(yè)務(wù)代碼使用這個函數(shù)需慎重。
?
總結(jié)
以上是生活随笔為你收集整理的Thread.yield()的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: quantaxis中使用docker安装
- 下一篇: java打印调用堆栈的方式