多線程上下文切換

一、CPU時間片
  • CPU時間片即CPU分配給每個線程的執(zhí)行時間段,稱作它的時間片惹盼。CPU時間片一般為幾十毫秒(ms)。
二惫确、什么是上下文切換

CPU通過時間片段的算法來循環(huán)執(zhí)行線程任務(wù)手报,而循環(huán)執(zhí)行即每個線程允許運(yùn)行的時間后的切換,而這種循環(huán)的切換使各個程序從表面上看是同時進(jìn)行的改化。而切換時會保存之前的線程任務(wù)狀態(tài)掩蛤,當(dāng)切換到該線程任務(wù)的時候,會重新加載該線程的任務(wù)狀態(tài)陈肛。而這個從保存到加載的過程稱之為上下文切換揍鸟。

  • 若當(dāng)前線程還在運(yùn)行而時間片結(jié)束后,CPU將被剝奪并分配給另一個線程句旱。
  • 若線程在時間片結(jié)束前阻塞或結(jié)束阳藻,CPU進(jìn)行線程切換。而不會造成CPU資源浪費(fèi)谈撒。
三腥泥、上下文切換造成的影響

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

    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)次數(shù),對比串行運(yùn)行和并發(fā)運(yùn)行的時間測試結(jié)果:

循環(huán)次數(shù) 并發(fā)執(zhí)行時間 串聯(lián)執(zhí)行時間
一百萬 2ms 4ms
十萬 2ms 2ms
一萬 1ms 0ms

通過數(shù)據(jù)的對比我們可以看出蛔外。在一萬以下的循環(huán)次數(shù)時蛆楞,串聯(lián)的執(zhí)行速度比并發(fā)的執(zhí)行速度塊。是因為線程上下文切換導(dǎo)致額外的開銷夹厌。

在Linux系統(tǒng)下可以使用vmstat命令來查看上下文切換的次數(shù)豹爹,如果要查看上下文切換的時長,可以利用Lmbench3尊流,這是一個性能分析工具帅戒。

四、如何減少上下文切換導(dǎo)致額外的開銷

減少上下文切換次數(shù)便可以提高多線程的運(yùn)行效率崖技。減少上下文切換的方法有無鎖并發(fā)編程、CAS算法钟哥、避免創(chuàng)建過多的線程和使用協(xié)程迎献。

  • 無鎖并發(fā)編程.當(dāng)任何特定的運(yùn)算被阻塞的時候,所有CPU可以繼續(xù)處理其他的運(yùn)算腻贰。換種方式說吁恍,在無鎖系統(tǒng)中,當(dāng)給定線程被其他線程阻塞的時候播演,所有CPU可以不停的繼續(xù)處理其他工作冀瓦。無鎖算法大大增加系統(tǒng)整體的吞吐量,因為它只偶爾會增加一定的交易延遲写烤。大部分高端數(shù)據(jù)庫系統(tǒng)是基于無鎖算法而構(gòu)造的翼闽,以滿足不同級別。

  • CAS算法洲炊。Java提供了一套原子性操作的數(shù)據(jù)類型(java.util.concurrent.atomic包下)感局,使用CAS算法來更新數(shù)據(jù),不需要加鎖暂衡。如:AtomicInteger询微、AtomicLong等。

  • 避免創(chuàng)建過多的線程狂巢。如任務(wù)量少時撑毛,盡可能減少創(chuàng)建線程。對于某個時間段任務(wù)量很大的這種情況唧领,我們可以通過線程池來管理線程的數(shù)量藻雌,避免創(chuàng)建過多線程。

  • 協(xié)程:即協(xié)作式程序疹吃,其思想是蹦疑,一系列互相依賴的協(xié)程間依次使用CPU,每次只有一個協(xié)程工作萨驶,而其他協(xié)程處于休眠狀態(tài)歉摧。如:JAVA中使用wait和notify來達(dá)到線程之間的協(xié)同工作。

參考:
《Java并發(fā)編程的藝術(shù)》

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市叁温,隨后出現(xiàn)的幾起案子再悼,更是在濱河造成了極大的恐慌,老刑警劉巖膝但,帶你破解...
    沈念sama閱讀 211,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件冲九,死亡現(xiàn)場離奇詭異,居然都是意外死亡跟束,警方通過查閱死者的電腦和手機(jī)莺奸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,347評論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來冀宴,“玉大人灭贷,你說我怎么就攤上這事÷灾” “怎么了甚疟?”我有些...
    開封第一講書人閱讀 157,435評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長逃延。 經(jīng)常有香客問我览妖,道長,這世上最難降的妖魔是什么揽祥? 我笑而不...
    開封第一講書人閱讀 56,509評論 1 284
  • 正文 為了忘掉前任讽膏,我火速辦了婚禮俄精,結(jié)果婚禮上陵霉,老公的妹妹穿的比我還像新娘啤誊。我一直安慰自己贩绕,他們只是感情好吉捶,可當(dāng)我...
    茶點故事閱讀 65,611評論 6 386
  • 文/花漫 我一把揭開白布斩松。 她就那樣靜靜地躺著变勇,像睡著了一般禀苦。 火紅的嫁衣襯著肌膚如雪站绪。 梳的紋絲不亂的頭發(fā)上遭铺,一...
    開封第一講書人閱讀 49,837評論 1 290
  • 那天,我揣著相機(jī)與錄音恢准,去河邊找鬼魂挂。 笑死,一個胖子當(dāng)著我的面吹牛馁筐,可吹牛的內(nèi)容都是我干的涂召。 我是一名探鬼主播,決...
    沈念sama閱讀 38,987評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼敏沉,長吁一口氣:“原來是場噩夢啊……” “哼果正!你這毒婦竟也來了炎码?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,730評論 0 267
  • 序言:老撾萬榮一對情侶失蹤秋泳,失蹤者是張志新(化名)和其女友劉穎潦闲,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體迫皱,經(jīng)...
    沈念sama閱讀 44,194評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡歉闰,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,525評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了卓起。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片和敬。...
    茶點故事閱讀 38,664評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖戏阅,靈堂內(nèi)的尸體忽然破棺而出概龄,到底是詐尸還是另有隱情,我是刑警寧澤饲握,帶...
    沈念sama閱讀 34,334評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站蚕键,受9級特大地震影響救欧,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜锣光,卻給世界環(huán)境...
    茶點故事閱讀 39,944評論 3 313
  • 文/蒙蒙 一笆怠、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧誊爹,春花似錦蹬刷、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,764評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至搂漠,卻和暖如春迂卢,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背桐汤。 一陣腳步聲響...
    開封第一講書人閱讀 31,997評論 1 266
  • 我被黑心中介騙來泰國打工而克, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人怔毛。 一個月前我還...
    沈念sama閱讀 46,389評論 2 360
  • 正文 我出身青樓员萍,卻偏偏與公主長得像,于是被迫代替她去往敵國和親拣度。 傳聞我的和親對象是個殘疾皇子碎绎,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,554評論 2 349