多線程上下文切換

一导街、CPU時間片

CPU時間片即CPU分配給每個線程的執(zhí)行時間段涝滴,稱作它的時間片恶座。

二便脊、什么是上下文切換

CPU通過給每個線程分配CPU時間片來實現這個機制蚂四。時間片是CPU分配給各個線程的時間,因為時間片非常短,所以CPU通過不停地切換線程執(zhí)行遂赠,讓我們感覺多個線程時同時執(zhí)行的久妆,時間片一般是幾十毫秒(ms)。
CPU通過時間片分配算法來循環(huán)執(zhí)行任務跷睦,當前任務執(zhí)行一個時間片后會切換到下一個任務筷弦。但是,在切換前會保存上一個任務的狀態(tài)送讲,以便下次切換回這個任務時奸笤,可以再次加載這個任務的狀態(tài),從任務保存到再加載的過程就是一次上下文切換哼鬓。

  • 若當前線程還在運行而時間片結束后监右,CPU將被剝奪并分配給另一個線程。
  • 若線程在時間片結束前阻塞或結束异希,CPU進行線程切換健盒。而不會造成CPU資源浪費。

三称簿、上下文切換造成的影響

我們可以通過對比串聯(lián)執(zhí)行和并發(fā)執(zhí)行進行對比扣癣。

  private static final long count = 1000000;

    public static void main(String[] args) throws Exception {
        concurrency();
        series();
    }
    /**
     * 并發(fā)執(zhí)行
     * @throws Exception
     */
    private static void concurrency() throws Exception {
        long start = System.currentTimeMillis();
        //創(chuàng)建線程執(zhí)行a+=
        Thread thread = new Thread(new Runnable() {
            public void run() {
                int a = 0;
                for (int i = 0; i < count; i++) {
                    a += 1;
                }
            }
        });
        //啟動線程執(zhí)行
        thread.start();
        //使用主線程執(zhí)行b--;
        int b = 0;
        for (long i = 0; i < count; i++) {
            b--;
        }
        //合并線程,統(tǒng)計時間
        thread.join();
        long time = System.currentTimeMillis() - start;
        System.out.println("Concurrency:" + time + "ms, b = " + b);
    }
    /**
     * 串聯(lián)執(zhí)行
     */
    private static void series() {
        long start = System.currentTimeMillis();
        int a = 0;
        for (long i = 0; i < count; i++) {
            a += 1;
        }
        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);
    }

通過修改循環(huán)次數,對比串行運行和并發(fā)運行的時間測試結果:



通過數據的對比我們可以看出憨降。在一萬以下的循環(huán)次數時父虑,串聯(lián)的執(zhí)行速度比并發(fā)的執(zhí)行速度塊。是因為線程上下文切換導致額外的開銷授药。

在Linux系統(tǒng)下可以使用vmstat命令來查看上下文切換的次數士嚎,如果要查看上下文切換的時長,可以利用Lmbench3悔叽,這是一個性能分析工具莱衩。

四、如何減少上下文切換導致額外的開銷

減少上下文切換次數便可以提高多線程的運行效率娇澎。減少上下文切換的方法有無鎖并發(fā)編程笨蚁、CAS算法、避免創(chuàng)建過多的線程和使用協(xié)程趟庄。

  • 無鎖并發(fā)編程.當任何特定的運算被阻塞的時候括细,所有CPU可以繼續(xù)處理其他的運算。換種方式說戚啥,在無鎖系統(tǒng)中勒极,當給定線程被其他線程阻塞的時候,所有CPU可以不停的繼續(xù)處理其他工作虑鼎。無鎖算法大大增加系統(tǒng)整體的吞吐量,因為它只偶爾會增加一定的交易延遲。大部分高端數據庫系統(tǒng)是基于無鎖算法而構造的炫彩,以滿足不同級別匾七。

  • CAS算法。Java提供了一套原子性操作的數據類型(java.util.concurrent.atomic包下)江兢,使用CAS算法來更新數據昨忆,不需要加鎖。如:AtomicInteger杉允、AtomicLong等邑贴。

  • 避免創(chuàng)建過多的線程。如任務量少時叔磷,盡可能減少創(chuàng)建線程拢驾。對于某個時間段任務量很大的這種情況,我們可以通過線程池來管理線程的數量改基,避免創(chuàng)建過多線程繁疤。

  • 協(xié)程:即協(xié)作式程序,其思想是秕狰,一系列互相依賴的協(xié)程間依次使用CPU稠腊,每次只有一個協(xié)程工作,而其他協(xié)程處于休眠狀態(tài)鸣哀。如:JAVA中使用wait和notify來達到線程之間的協(xié)同工作架忌。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市我衬,隨后出現的幾起案子叹放,更是在濱河造成了極大的恐慌,老刑警劉巖低飒,帶你破解...
    沈念sama閱讀 221,635評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件许昨,死亡現場離奇詭異,居然都是意外死亡褥赊,警方通過查閱死者的電腦和手機糕档,發(fā)現死者居然都...
    沈念sama閱讀 94,543評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來拌喉,“玉大人速那,你說我怎么就攤上這事∧虮常” “怎么了端仰?”我有些...
    開封第一講書人閱讀 168,083評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長田藐。 經常有香客問我荔烧,道長吱七,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,640評論 1 296
  • 正文 為了忘掉前任鹤竭,我火速辦了婚禮踊餐,結果婚禮上,老公的妹妹穿的比我還像新娘臀稚。我一直安慰自己吝岭,他們只是感情好,可當我...
    茶點故事閱讀 68,640評論 6 397
  • 文/花漫 我一把揭開白布吧寺。 她就那樣靜靜地躺著窜管,像睡著了一般。 火紅的嫁衣襯著肌膚如雪稚机。 梳的紋絲不亂的頭發(fā)上幕帆,一...
    開封第一講書人閱讀 52,262評論 1 308
  • 那天,我揣著相機與錄音抒钱,去河邊找鬼蜓肆。 笑死,一個胖子當著我的面吹牛谋币,可吹牛的內容都是我干的仗扬。 我是一名探鬼主播,決...
    沈念sama閱讀 40,833評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼蕾额,長吁一口氣:“原來是場噩夢啊……” “哼早芭!你這毒婦竟也來了?” 一聲冷哼從身側響起诅蝶,我...
    開封第一講書人閱讀 39,736評論 0 276
  • 序言:老撾萬榮一對情侶失蹤退个,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后调炬,有當地人在樹林里發(fā)現了一具尸體语盈,經...
    沈念sama閱讀 46,280評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,369評論 3 340
  • 正文 我和宋清朗相戀三年缰泡,在試婚紗的時候發(fā)現自己被綠了刀荒。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,503評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡棘钞,死狀恐怖缠借,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情宜猜,我是刑警寧澤泼返,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站姨拥,受9級特大地震影響绅喉,放射性物質發(fā)生泄漏渠鸽。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,870評論 3 333
  • 文/蒙蒙 一霹疫、第九天 我趴在偏房一處隱蔽的房頂上張望拱绑。 院中可真熱鬧,春花似錦丽蝎、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至额各,卻和暖如春国觉,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背虾啦。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評論 1 272
  • 我被黑心中介騙來泰國打工麻诀, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留傲醉,地道東北人呻引。 一個月前我還...
    沈念sama閱讀 48,909評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像吐咳,于是被迫代替她去往敵國和親逻悠。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,512評論 2 359

推薦閱讀更多精彩內容

  • 一韭脊、CPU時間片 CPU時間片即CPU分配給每個線程的執(zhí)行時間段童谒,稱作它的時間片饥伊。CPU時間片一般為幾十毫秒(ms...
    barry_di閱讀 6,640評論 0 1
  • 1、背景 并發(fā)編程的目的是為了讓程序運行得更快任内,但是并不是啟動更多的線程就能讓程序最大 限度地并發(fā)執(zhí)行撵渡。在進行并發(fā)...
    maerzi閱讀 328評論 0 2
  • java 中的多線程在代碼層面是通過 new 多個 Thread 或是線程池實現的,這只是表象越除,我們需要繼續(xù)審圖探...
    前行的烏龜閱讀 1,575評論 0 3
  • 0 前言 在過去單CPU時代节腐,單任務在一個時間點只能執(zhí)行單一程序外盯。之后發(fā)展到多任務階段,計算機能在同一時間點并行執(zhí)...
    七寸知架構閱讀 9,939評論 6 95
  • 多線程-上下文切換: 即使是單核處理器也支持多線程執(zhí)行代碼翼雀,CPU通過給每個線程分配cpu時間片來實現這個機制...
    caibixiang閱讀 351評論 0 0