1. 程式人生 > >多執行緒--上下文切換

多執行緒--上下文切換

在開發的過程中,多執行緒一直很受歡迎,因為它的執行速度比序列要快,但是到底快多少呢?一定快麼?下面我們用一段程式碼來測試下

private static final long count = 100000;

    public static void main(String[] args) throws InterruptedException {
        concurrency();
        serial();
    }

    public static void concurrency() throws InterruptedException{
        long
start = System.currentTimeMillis(); Thread thread = new Thread(new Runnable() { public void run() { 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(); long time = System.currentTimeMillis() - start; System.out.println("concurrency : " + time + "ms,b = " + b); } public static void serial(){ long start = System.currentTimeMillis(); int
a = 0; for(int i=0;i<count;i++){ a += 5; } int b = 0; for(long i = 0;i < count;i++){ b--; } long time = System.currentTimeMillis() - start; System.out.println("serial : " + time + "ms,b = " + b + ",a = " + a); }

我們來看一些執行結果:
當count = 10000時 輸出:concurrency : 1ms,b = -10000 serial : 0ms,b = -10000,a = 50000
當count = 100000時 輸出:concurrency : 2ms,b = -100000 serial : 3ms,b = -100000,a = 500000
當count = 1000000時 輸出:concurrency : 5ms,b = -1000000 serial : 3ms,b = -1000000,a = 5000000
當count = 10000000時 輸出:concurrency : 7ms,b = -10000000 serial : 11ms,b = -10000000,a = 50000000
當count = 100000000時 輸出:concurrency : 48ms,b = -100000000 serial : 84ms,b = -100000000,a = 500000000

當運算次數越少的時候,序列執行反而比多執行緒快,為什麼會出現這樣的情況?多執行緒為什麼會執行的慢呢?

其實CPU在執行多執行緒的時候時通過給每個執行緒分配CPU時間段來實現多執行緒的,時間片時CPU分配給各個執行緒的時間,因為時間片非常短(一般在幾十毫秒),所以CPU通過不停的切換執行緒執行,才能讓我們感覺到多個執行緒在同時執行。但是CPU線上程之間的切換前要保留上一個執行緒的狀態,同時載入當前執行緒的狀態,在這個操作過程中也就差生了一定的時間消耗。同時沒操作一次,也就完成了一次上下文切換。

如何減少上下文切換?
1、無所併發程式設計。多執行緒競爭鎖才會引起上下文切換,所以多執行緒處理資料時可以儘量避免使用鎖,如不同執行緒處理不同段的資料
2、使用最少執行緒。避免建立不必要的執行緒,避免大量執行緒處於等待狀態
3、協程。在單執行緒裡面實現多工排程,並維持多工之間的切換。