並發 和 並行 的區別
推薦閱讀:https://www.zhihu.com/question/33515481
並發:有處理多個任務的能力,不一定要同時。
並行:有同時處理多個任務的能力。
多線程似乎一直給我們這樣的印象就是多線程比單線程快,其實這是一個偽命題.事無絕對,多線程有時候確實比單線程快,但也有很多時候沒有單線程那么快. 首先簡單區分一下並發性(concurrency)和並行性(parallel).並行是說同一時刻有多條命令在多個處理器上同時執行.並發是說同一時刻只有一條指令執行,只不過進程(線程)指令在CPU中快速輪換,速度極快,給人看起來就是”同時運行”的印象,實際上同一時刻只有一條指令進行. 但實際上如果我們在一個應用程序中使用了多線程,線程之間的輪換以及上下文切換是需要花費很多時間的,這樣的話當我們執行類似循環之類的操作的時候,是不是就意味着單線程一定會比多線程快呢(因為單線程的執行沒有線程切換的時間消耗),看下面一段代碼(出自<<Java並發編程的藝術>>)
public class ConcurrencyTest { private static final long count = 1000000000; public static void main(String[] args) { try { concurrency(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } 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; } } }); 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("concurrency : " + time + "ms,b=" + b); } }
這段代碼的運行結果是當count值比較小的時候單線程的運行速度比多線程要快,當count的值比較大的時候多線程的速度大概會是單線程的兩倍為什么會這樣呢,理論上來說執行上述這種代碼操作單線程不需要上下文切換應該肯定比多線程要快才對呀. 其實是因為我們異想天開了,CPU的資源又不是全部都給你這個Java程序使用的,別的程序也要占用CPU資源啊.比如說當我們這個程序還沒有運行的時候其實可能操作系統中已經有50個線程在運行了,那么當我們這個程序運行的時候,單線程就會占用CPU51分之1的時間(假設每個線程占用時間相等),多線程就會占用CPU52分之2的時間,你說哪個會運行的更快呢.當然當數量比較少的時候上下文之間的輪換會占用相對較多的時間所以這個時候雖然多線程占用CPU52分之2的時間,但是切換也需要很多的時間所以就比單線程要慢
.
