併發程式設計-1-概述
阿新 • • 發佈:2019-01-04
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節的併發工具用於解決併發問題