併發編程之併發編程的挑戰

關於併發編程,其目的就是爲了讓程序運行得更快,但是,並不是啓動更多的線程就能讓程序更大限度的併發執行。有哪些影響併發編程的因素呢?

一、文章導圖

併發編程的挑戰

二、挑戰

1、上下文切換

單核處理器也支持多線程執行代碼,CPU通過給每個線程分配CPU時間片來實現這個機制,只是時間片的時間短,感覺CPU能同時處理多個任務。時間片一般是幾十毫秒(ms)。
CPU通過時間片輪訓的方式處理任務,當前任務執行一個時間片會切換到下一個任務。注意,當CPU從一個任務切換到另一個任務前,會保留上一個任務的狀態,以便再切回來是可以繼續執行。所以任務從保持狀態到再加載的過程就是一次上下文切換

  • 多線程執行耗時測試
電腦配置:單處理器雙核8G內存
public class Demo1_1_1 {

    private static final long count = 1000000001;

    public static void main(String[] args) throws InterruptedException {
        // 註釋一個進行執行
        concurrent();
//        serial();
    }

    /**
     * 併發執行
     */
    private static void concurrent() throws InterruptedException {
        long start = System.currentTimeMillis();
        Thread thread = new Thread(() -> {
            int a = 0;
            for (long i = 0; i < count; i++) {
                a += 5;
            }
        });
        thread.start();

        int b = 0;
        for (long i = 0; i < count; i++) {
            b --;
        }
        thread.join();
        System.out.println("concurrent time:" + (System.currentTimeMillis() - start) + "ms");

    }

    /**
     * 串行執行
     */
    private static void serial() {
        long start = System.currentTimeMillis();
        int a = 0;
        for (long i = 0; i < count; i++) {
            a += 5;
        }

        int b = 0;
        for (long i = 0; i < count; i++) {
            b --;
        }
        System.out.println("serial time:" + (System.currentTimeMillis() - start) + "ms");
    }

}
以上分別執行3次,取一個最大值和一個最小值

結果

循環次數 並行耗時/ms 串行耗時/ms
10萬 66 - 90 2 - 4
100萬 68 - 78 5 - 13
1000萬 75 - 81 16 - 19
1億 133 - 128 80 - 121
10億 600 - 615 900 - 1000

分析
當併發執行不超過億級別時,並行是比串行慢的,這就是因爲線程有創建和上下文切換的開銷。按理說多個線程執行應該比單線程慢,實際並非如此。

  • 如何減少上下文切換

1、無所併發編程:多線程競爭鎖時,會引發上下文切換
2、CAS算法:Java中的Atomic包使用CAS算法更新數據,無需加鎖
3、使用最少線程:任務少,但線程多,導致很多線程都處於等待狀態
4、協程:在線程裏實現多線程的調度

2、死鎖

java中的鎖主要用來解決併發編程資源競爭的問題,如果編程不當,一旦產生死鎖,便會導致系統功能不可用。

例如,有兩個線程t1,t2;兩個資源A,B;當出現,t1持有A資源,t2持有B資源時,t1嘗試獲取B資源,t2嘗試獲取A資源,此時,便會出現死鎖的情況。
  • 避免死鎖的辦法

1、避免一個線程同時獲取多個鎖
2、避免一個線程在鎖內同時佔有多個資源,盡力保證每個線程只佔用一個資源
3、嘗試使用定時鎖,如lock.tryLock(timeout)

3、資源限制的挑戰

  • 什麼是資源限制

資源限制指在進行併發編程時,程序的執行速度受限於計算機硬件資源或軟件資源。
硬件資源包括:帶寬的上傳下載速度、硬盤讀寫速度和CPU的處理速度等
軟件資源包括:線程池大小、數據庫的連接數等

  • 資源限制引發的問題

在併發編程中,代碼執行速度加快的原則是將代碼中的串行部分變成並行執行,但有可能由於資源限制問題,導致程序仍按串行執行,此時程序不僅不會變快,反而更慢,因爲增加了上下文切換和資源調度的時間。

  • 如何解決資源限制的問題

對於硬件資源限制:考慮使用集羣方式並行執行程序。
對於軟件資源限制:考慮使用資源池將資源複用,例如數據庫連接池等

  • 資源限制情況下進行併發編程

根據不同的資源限制調整程序的併發度。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章