1. 程式人生 > >併發程式設計-1-概述

併發程式設計-1-概述

1.併發程式設計概述

1.1併發程式設計目的

併發程式設計的目的

提高使用者體驗,提高程式效率
對單核處理器,併發程式設計使程式在邏輯上同時發生。

對多核處理器,除了邏輯上同時發生外,還可能使程式並行,提升程式效率。

併發與並行

併發:同時開始
並行:同時進行
關係:並行是併發的子集
其他併發並行的解釋:
  • 併發:一個處理器同時處理多個任務。

  • 並行:多個處理器或者是多核的處理器同時處理多個不同的任務.

前者是邏輯上的同時發生(simultaneous),而後者是物理上的同時發生.

1.2併發程式設計的執行緒開銷問題

執行緒開銷包括:

1.2.1執行緒建立開銷

執行緒建立開銷演示

[CODE]:multi-thread-playground/multithread.artConcurrencyProgramming.chapter01.ConcurrencyTest

public class ConcurrencyTest {

    /** 執行次數 */
    private static final long count = 10000l;

    public static void main(String[] args) throws InterruptedException {
        //併發計算
        concurrency();
        //單執行緒計算
        serial();
    }

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

}

建立消耗資料統計

測試機器效能

MacOs 10.12.3 2.2GHz Intel Core i7 16GB

count(迴圈次數)

serial(ms)

concurrency(ms)

1w

0

2

10w

3

4

100w

6

5

1000w

19

12

總結:執行緒建立的開銷需要考慮在內

1.2.2上下文切換開銷

上下文切換開銷演示

public class ConcurrencySwitchTest {

    /** 執行次數 */
    private static final long count = 10000000l;

    /** 任務數*/
    static final int taskNum = 50;
  
 		static final int threadPoolNum = 6;

    static ExecutorService executor = Executors.newFixedThreadPool(threadPoolNum);

    public static void main(String[] args) throws InterruptedException {
        //併發計算
        concurrency();
    }

    private static void concurrency() throws InterruptedException {
        long start = System.currentTimeMillis();

        List<Thread> threads = new ArrayList<Thread>();

        for(int i=0;i<taskNum;i++) {
            final int j = i;
            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    if(j%2==0) {
                        add();
                    }else{
                        minus();
                    }
                }
            });

            threads.add(thread);
        }
        for (Thread t: threads) {
            executor.execute(t);
        }
        executor.shutdown();
        // Wait until all threads are finish
        executor.awaitTermination(100, TimeUnit.SECONDS);
        long time = System.currentTimeMillis() - start;
        System.out.println("concurrency :" + time + "ms");
    }


    private static void add(){
        int a = 0;
        for (long i = 0; i < count; i++) {
            a += 5;
        }
    }
    private static void minus(){
        int b = 0;
        for (long i = 0; i < count; i++) {
            b--;
        }
    }
}

上下文切換資料統計

threadPoolNum

耗時(ms)

2

102

3

71

4

65

5

82

10

103

20

141

1.3併發程式設計的併發問題

章2節的併發工具用於解決併發問題