第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

多線程 yield 方法

1. 前言

本節(jié)對(duì) yield 方法進(jìn)行深入的剖析,主要內(nèi)容點(diǎn)如下:

  • 首先要了解什么是 CPU 執(zhí)行權(quán),因?yàn)?yield 方法與 CPU 執(zhí)行權(quán)息息相關(guān);
  • 了解 yield 方法的作用,要明確 yield 方法的使用所帶來(lái)的運(yùn)行效果;
  • 了解什么是 native 方法,由于 yield 方法是 native 方法的調(diào)用,在學(xué)習(xí) yield 方法之前,要了解什么是 native 方法;
  • 掌握 yield 方法如何使用,這是本節(jié)知識(shí)點(diǎn)的重中之重,一定要著重學(xué)習(xí);
  • 了解 yield 方法和 sleep 方法的區(qū)別,進(jìn)行對(duì)比記憶,更有助于掌握該方法的獨(dú)有特性。

2. 什么是 CPU 執(zhí)行權(quán)

我們知道操作系統(tǒng)是為每個(gè)線程分配一個(gè)時(shí)間片來(lái)占有 CPU 的,正常情況下當(dāng)一個(gè)線程把分配給自己的時(shí)間片使用完后,線程調(diào)度器才會(huì)進(jìn)行下一輪的線程調(diào)度,這里所說(shuō)的 “自己占有的時(shí)間片” 即 CPU 分配給線程的執(zhí)行權(quán)。

那進(jìn)一步進(jìn)行探究,何為讓出 CPU 執(zhí)行權(quán)呢?
當(dāng)一個(gè)線程通過(guò)某種可行的方式向操作系統(tǒng)提出讓出 CPU 執(zhí)行權(quán)時(shí),就是在告訴線程調(diào)度器自己占有的時(shí)間片中還沒(méi)有使用完的部分自己不想使用了,主動(dòng)放棄剩余的時(shí)間片,并在合適的情況下,重新獲取新的執(zhí)行時(shí)間片。

3. yield 方法的作用

方法介紹:Thread 類中有一個(gè)靜態(tài)的 yield 方法,當(dāng)一個(gè)線程調(diào)用 yield 方法時(shí),實(shí)際就是在暗示線程調(diào)度器當(dāng)前線程請(qǐng)求讓出自己的 CPU 使用權(quán)。

public static native void yield();

Tips:從這個(gè)源碼中我們能夠看到如下兩點(diǎn)要點(diǎn):

  1. yield 方法是一個(gè)靜態(tài)方法,靜態(tài)方法的特點(diǎn)是可以由類直接進(jìn)行調(diào)用,而不需要進(jìn)行對(duì)象 new 的創(chuàng)建,調(diào)用方式為 Thread.yield ()。
  2. 該方法除了被 static 修飾,還被 native 修飾,那么進(jìn)入主題,什么是 native 方法呢?我們繼續(xù)來(lái)看下文的講解。

抽象地講,一個(gè) Native Method 就是一個(gè) Java 調(diào)用的非 Java 代碼的接口。一個(gè) Native Method 是這樣一個(gè) Java 的方法:該方法的實(shí)現(xiàn)由非 java 語(yǔ)言實(shí)現(xiàn)。

簡(jiǎn)單的來(lái)說(shuō),native 方法就是我們自己電腦的方法接口,比如 Windows 電腦會(huì)提供一個(gè) yield 方法,Linux 系統(tǒng)的電腦也同樣會(huì)提供一個(gè) yield 方法,本地方法,可以理解為操作調(diào)用操作系統(tǒng)的方法接口。

作用:暫停當(dāng)前正在執(zhí)行的線程對(duì)象(及放棄當(dāng)前擁有的 cup 資源),并執(zhí)行其他線程。yield () 做的是讓當(dāng)前運(yùn)行線程回到可運(yùn)行狀態(tài),以允許具有相同優(yōu)先級(jí)的其他線程獲得運(yùn)行機(jī)會(huì)。

目的:yield 即 “謙讓”,使用 yield () 的目的是讓具有相同優(yōu)先級(jí)的線程之間能適當(dāng)?shù)妮嗈D(zhuǎn)執(zhí)行。但是,實(shí)際中無(wú)法保證 yield () 達(dá)到謙讓目的,因?yàn)榉艞?CPU 執(zhí)行權(quán)的線程還有可能被線程調(diào)度程序再次選中。

4. yield 方法如何使用

為了更好的了解 yield 方法的使用,我們首先來(lái)設(shè)計(jì)一個(gè)使用的場(chǎng)景。
場(chǎng)景設(shè)計(jì)

  • 創(chuàng)建一個(gè)線程,線程名為 threadOne;
  • 打印一個(gè)數(shù),該數(shù)的值為從 1 加到 10000000 的和;
  • 不使用 yield 方法正常執(zhí)行,記錄總的執(zhí)行時(shí)間;
  • 加入 yield 方法,再次執(zhí)行程序;
  • 再次記錄總執(zhí)行時(shí)間。

期望結(jié)果: 未加入 yield 方法之前打印的時(shí)間 < 加入 yield 方法之后的打印時(shí)間。因?yàn)?yield 方法在執(zhí)行過(guò)程中會(huì)放棄 CPU 執(zhí)行權(quán)并從新獲取新的 CPU 執(zhí)行權(quán)。

代碼實(shí)現(xiàn) - 正常執(zhí)行

public class DemoTest extends Thread {
    @Override
    public void run() {
        Long start = System.currentTimeMillis();
        int count = 0;
        for (int i = 1; i <= 10000000; i++) {
             count = count + i;
        }
        Long end = System.currentTimeMillis();
        System.out.println("總執(zhí)行時(shí)間: "+ (end-start) + " 毫秒, 結(jié)果 count = " + count);
    }

    public static void main(String[] args) throws InterruptedException {
        DemoTest threadOne = new DemoTest();
        threadOne. start();
    }
}

執(zhí)行結(jié)果驗(yàn)證

總執(zhí)行時(shí)間: 6 毫秒. 

代碼實(shí)現(xiàn) - yield 執(zhí)行

public class DemoTest extends Thread {
    @Override
    public void run() {
        Long start = System.currentTimeMillis();
        int count = 0;
        for (int i = 1; i <= 10000000; i++) {
             count = count + i;
             this.yield(); // 加入 yield 方法
        }
        Long end = System.currentTimeMillis();
        System.out.println("總執(zhí)行時(shí)間: "+ (end-start) + " 毫秒. ");
    }

    public static void main(String[] args) throws InterruptedException {
        DemoTest threadOne = new DemoTest();
        threadOne. start();
    }
}

執(zhí)行結(jié)果驗(yàn)證

總執(zhí)行時(shí)間: 5377 毫秒. 

從執(zhí)行的結(jié)果來(lái)看,與我們對(duì) yield 方法的理解和分析完全相符,請(qǐng)同學(xué)也進(jìn)行代碼的編寫和運(yùn)行,加深學(xué)習(xí)印象。當(dāng)加入 yield 方法執(zhí)行時(shí),線程會(huì)放棄 CPU 的執(zhí)行權(quán),并等待再次獲取新的執(zhí)行權(quán),所以執(zhí)行時(shí)間上會(huì)更加的長(zhǎng)。

5. yield 方法和 sleep 方法的區(qū)別

  • sleep () 方法給其他線程運(yùn)行機(jī)會(huì)時(shí)不考慮線程的優(yōu)先級(jí),因此會(huì)給低優(yōu)先級(jí)的線程以運(yùn)行的機(jī)會(huì);
  • yield () 方法只會(huì)給相同優(yōu)先級(jí)或更高優(yōu)先級(jí)的線程以運(yùn)行的機(jī)會(huì);
  • 線程執(zhí)行 sleep () 方法后轉(zhuǎn)入阻塞 (blocked) 狀態(tài),而執(zhí)行 yield () 方法后轉(zhuǎn)入就緒 (ready) 狀態(tài);
  • sleep () 方法聲明會(huì)拋出 InterruptedException, 而 yield () 方法沒(méi)有聲明任何異常;
  • sleep () 方法比 yield () 方法具有更好的移植性 (跟操作系統(tǒng) CPU 調(diào)度相關(guān))。

6. 小結(jié)

在實(shí)際的開(kāi)發(fā)場(chǎng)景中,yield 方法的使用場(chǎng)景比較少,但是對(duì)于并發(fā)原理知識(shí)的學(xué)習(xí)過(guò)程,對(duì) yield 方法的了解非常重要,有助于同學(xué)了解不同狀態(tài)下的線程的不同狀態(tài)。
本節(jié)要重點(diǎn)掌握 yield 方法的作用以及如何使用 yield 方法。