最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

關(guān)于Java多線程上下文切換的總結(jié)

 更新時(shí)間:2023年05月09日 09:39:15   作者:九月木碼  
CPU通過(guò)時(shí)間片分配算法來(lái)循環(huán)執(zhí)行任務(wù),當(dāng)前任務(wù)執(zhí)行一個(gè)時(shí)間片后會(huì)切換到下一個(gè)任務(wù)。但是,在切換前會(huì)保存上一個(gè)任務(wù)的狀態(tài),以便下次切換回這個(gè)任務(wù)時(shí),可以再次加載這個(gè)任務(wù)的狀態(tài),從任務(wù)保存到再加載的過(guò)程就是一次上下文切換,需要的朋友可以參考下

什么是上下文切換

即使是單核CPU也支持多線程執(zhí)行代碼,CPU通過(guò)給每個(gè)線程分配CPU時(shí)間片來(lái)實(shí)現(xiàn)這個(gè)機(jī)制。時(shí)間片是CPU分配給各個(gè)線程的時(shí)間,因?yàn)闀r(shí)間片非常短,所以CPU通過(guò)不停地切換線程執(zhí)行,讓我們感覺(jué)多個(gè)線程時(shí)同時(shí)執(zhí)行的,時(shí)間片一般是幾十毫秒(ms)。

CPU通過(guò)時(shí)間片分配算法來(lái)循環(huán)執(zhí)行任務(wù),當(dāng)前任務(wù)執(zhí)行一個(gè)時(shí)間片后會(huì)切換到下一個(gè)任務(wù)。但是,在切換前會(huì)保存上一個(gè)任務(wù)的狀態(tài),以便下次切換回這個(gè)任務(wù)時(shí),可以再次加載這個(gè)任務(wù)的狀態(tài),從任務(wù)保存到再加載的過(guò)程就是一次上下文切換。

這就像我們同時(shí)讀兩本書(shū),當(dāng)我們?cè)谧x一本英文的技術(shù)書(shū)籍時(shí),發(fā)現(xiàn)某個(gè)單詞不認(rèn)識(shí),于是便打開(kāi)中英文詞典,但是在放下英文書(shū)籍之前,大腦必須先記住這本書(shū)讀到了多少頁(yè)的第多少行,等查完單詞之后,能夠繼續(xù)讀這本書(shū)。這樣的切換是會(huì)影響讀書(shū)效率的,同樣上下文切換也會(huì)影響多線程的執(zhí)行速度。

上下文切換代碼測(cè)試

下面的代碼演示串行和并發(fā)執(zhí)行并累加操作的時(shí)間:

public class ContextSwitchTest
{
    private static final long count = 10000;
    public static void main(String[] args) throws Exception
    {
        concurrency();
        serial();
    }
    private static void concurrency() throws Exception
    {
        long start = System.currentTimeMillis();
        Thread thread = new Thread(new Runnable(){
            public void run()
            {
                int a = 0;
                for (int i = 0; i < count; i++)
                {
                    a += 5;
                }
            }
        });
        thread.start();
        int b = 0;
        for (long i = 0; i < count; i++)
        {
            b --;
        }
        thread.join();
        long time = System.currentTimeMillis() - start;
        System.out.println("Concurrency:" + time + "ms, b = " + b);
    }
    private static void serial()
    {
        long start = System.currentTimeMillis();
        int a = 0;
        for (long i = 0; i < count; i++)
        {
            a += 5;
        }
        int b = 0;
        for (int i = 0; i < count; i++)
        {
            b --;
        }
        long time = System.currentTimeMillis() - start;
        System.out.println("Serial:" + time + "ms, b = " + b + ", a = " + a);
    }
}

修改上面的count值,即修改循環(huán)次數(shù),看一下串行運(yùn)行和并發(fā)運(yùn)行的時(shí)間測(cè)試結(jié)果:

從表中可以看出,100次并發(fā)執(zhí)行累加以下,串行執(zhí)行和并發(fā)執(zhí)行的運(yùn)行速度總體而言差不多,1萬(wàn)次以下串行執(zhí)行甚至還可以說(shuō)是略快。為什么并發(fā)執(zhí)行的速度會(huì)比串行慢呢?這就是因?yàn)?strong>線程有創(chuàng)建和上下文切換的開(kāi)銷。

引起線程上下文切換的原因

對(duì)于我們經(jīng)常使用的搶占式操作系統(tǒng)而言,引起線程上下文切換的原因大概有以下幾種:

  • 當(dāng)前執(zhí)行任務(wù)的時(shí)間片用完之后,系統(tǒng)CPU正常調(diào)度下一個(gè)任務(wù)
  • 當(dāng)前執(zhí)行任務(wù)碰到IO阻塞,調(diào)度器將此任務(wù)掛起,繼續(xù)下一任務(wù)
  • 多個(gè)任務(wù)搶占鎖資源,當(dāng)前任務(wù)沒(méi)有搶到鎖資源,被調(diào)度器掛起,繼續(xù)下一任務(wù)
  • 用戶代碼掛起當(dāng)前任務(wù),讓出CPU時(shí)間
  • 硬件中斷

如何減少上下文切換

既然上下文切換會(huì)導(dǎo)致額外的開(kāi)銷,因此減少上下文切換次數(shù)便可以提高多線程程序的運(yùn)行效率。減少上下文切換的方法有無(wú)鎖并發(fā)編程、CAS算法、使用最少線程和使用協(xié)程。

  • 無(wú)鎖并發(fā)編程。多線程競(jìng)爭(zhēng)時(shí),會(huì)引起上下文切換,所以多線程處理數(shù)據(jù)時(shí),可以用一些辦法來(lái)避免使用鎖,如將數(shù)據(jù)的ID按照Hash取模分段,不同的線程處理不同段的數(shù)據(jù)
  • CAS算法。Java的Atomic包使用CAS算法來(lái)更新數(shù)據(jù),而不需要加鎖
  • 使用最少線程。避免創(chuàng)建不需要的線程,比如任務(wù)很少,但是創(chuàng)建了很多線程來(lái)處理,這樣會(huì)造成大量線程都處于等待狀態(tài)
  • 協(xié)程。在單線程里實(shí)現(xiàn)多任務(wù)的調(diào)度,并在單線程里維持多個(gè)任務(wù)間的切換

到此這篇關(guān)于關(guān)于Java多線程上下文切換的總結(jié)的文章就介紹到這了,更多相關(guān)Java多線程上下文切換內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java實(shí)現(xiàn)字符串和日期類型相互轉(zhuǎn)換的方法

    java實(shí)現(xiàn)字符串和日期類型相互轉(zhuǎn)換的方法

    這篇文章主要介紹了java實(shí)現(xiàn)字符串和日期類型相互轉(zhuǎn)換的方法,涉及java針對(duì)日期與字符串的轉(zhuǎn)換與運(yùn)算相關(guān)操作技巧,需要的朋友可以參考下
    2017-02-02
  • 分布式鎖實(shí)例教程之防止重復(fù)提交

    分布式鎖實(shí)例教程之防止重復(fù)提交

    訂單重復(fù)問(wèn)題已經(jīng)是老生常談的問(wèn)題了,下面這篇文章主要給大家介紹了關(guān)于分布式鎖實(shí)例教程之防止重復(fù)提交的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2021-11-11
  • Java安全后端返回文件流方式

    Java安全后端返回文件流方式

    這篇文章主要介紹了Java安全后端返回文件流方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • 使用SpringBoot讀取Windows共享文件的代碼示例

    使用SpringBoot讀取Windows共享文件的代碼示例

    在現(xiàn)代企業(yè)環(huán)境中,文件共享是一個(gè)常見(jiàn)的需求,Windows共享文件夾(SMB/CIFS協(xié)議)因其易用性和廣泛的兼容性,成為了許多企業(yè)的首選,在Java應(yīng)用中,尤其是使用Spring Boot框架時(shí),如何讀取Windows共享文件是一個(gè)值得探討的話題,本文介紹了使用SpringBoot讀取Windows共享文件
    2024-11-11
  • Java編程倒計(jì)時(shí)實(shí)現(xiàn)方法示例

    Java編程倒計(jì)時(shí)實(shí)現(xiàn)方法示例

    這篇文章主要介紹了Java編程倒計(jì)時(shí)實(shí)現(xiàn)的三個(gè)示例,三種實(shí)現(xiàn)方法,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-09-09
  • knife4j3.0.3整合gateway和注冊(cè)中心的詳細(xì)過(guò)程

    knife4j3.0.3整合gateway和注冊(cè)中心的詳細(xì)過(guò)程

    這篇文章主要介紹了knife4j3.0.3整合gateway和注冊(cè)中心的詳細(xì)過(guò)程,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-03-03
  • Hibernate的各種保存方式的區(qū)別詳解

    Hibernate的各種保存方式的區(qū)別詳解

    今天小編就為大家分享一篇關(guān)于Hibernate的各種保存方式的區(qū)別詳解,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2019-03-03
  • Spring Boot 通過(guò)注解實(shí)現(xiàn)數(shù)據(jù)校驗(yàn)的方法

    Spring Boot 通過(guò)注解實(shí)現(xiàn)數(shù)據(jù)校驗(yàn)的方法

    這篇文章主要介紹了Spring Boot 通過(guò)注解實(shí)現(xiàn)數(shù)據(jù)校驗(yàn)的方法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-09-09
  • 給Java文件打成獨(dú)立JAR包的詳細(xì)步驟記錄

    給Java文件打成獨(dú)立JAR包的詳細(xì)步驟記錄

    這篇文章主要介紹了給Java文件打成獨(dú)立JAR包的相關(guān)資料,文中將Java文件打包成獨(dú)立的JAR包,包括非Maven和Maven項(xiàng)目的打包步驟,需要的朋友可以參考下
    2024-12-12
  • java token生成和校驗(yàn)的實(shí)例代碼

    java token生成和校驗(yàn)的實(shí)例代碼

    這篇文章主要介紹了java token生成和校驗(yàn)的實(shí)例代碼,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-09-09

最新評(píng)論

镇巴县| 余姚市| 佛教| 正蓝旗| 保亭| 定州市| 大邑县| 鄄城县| 彩票| 浏阳市| 花莲市| 西城区| 揭阳市| 如东县| 甘洛县| 宁武县| 胶州市| 时尚| 桓台县| 凤翔县| 驻马店市| 彩票| 锦州市| 获嘉县| 蒲江县| 临夏县| 山东省| 平南县| 夹江县| 明光市| 全南县| 澄城县| 泰兴市| 郸城县| 蕲春县| 汝州市| 资溪县| 灵璧县| 沭阳县| 石景山区| 松江区|