『單』線程能實現『并發』嗎?
多線程可以實現并發是毋庸置疑的,但是單線程是否能實現并發呢?
這就像我們知道多個人肯定可以同時做多件事,然后有人問一個人可以同時做多件事嗎?答案當然也是可以。比如很多人就經常邊吃飯邊玩手機,在工作中一個人也經常被上級同時安排大大小小多個任務。線程也是同理,所以單線程可以實現并發。
看到有人在也是回答“能”的情況下,說單線程實現的并發是“偽并發”,個人覺得這種說法是有問題的。并發就是并發,并不存在所謂“偽并發”。我大概也能猜到提出“偽并發”概念的人的意思,他認為的“真并發”其實是“并行”,其認為無法實現并行的并發就是“偽并發”。
但是,在弄清楚“并發”和“并行”兩個概念后,就會發現所謂“偽并發”是個多余、甚至會加重誤解的概念。并發說的是可以同時進行多個任務,但是它并不承諾這多個任務是“絕對的同時”開始,也不承諾多個任務是“絕對的同時”進行,而實現了后兩者的情況則被稱為“并行”。
即并發不一定并行,但是并行一定是并發。
在談論并發時所說的“同時”的“時”是個相對的、可變的“時間刻度”。兩件事是否算并發,隨著這個“時間刻度”的變化也會發生變化。比如前文說很多人經常邊吃飯邊玩手機是并發,較真的人可能就會不同意,覺得兩件事明明只能先后進行,原因就在于我和他在談論并發時的“時間刻度”沒統一。
假設某人吃飯大概10分鐘時間,于是將10分鐘視為一個不可分割的時間單位,如果在這個時間單位內還可以做其他事,就是實現了并發。但另一個人覺得并發的“時間刻度”最多為1秒,而1秒時間內顯然不能邊吃飯邊做其他事,于是他認為并發不成立。其實兩種說法都沒問題,只是并發的尺度不同。
并發是個應用場景遠大于并行,且在具體表現上可以非常靈活的執行機制。比如計算機領域的單核處理器可以做多并發,一個人做事也可以是多并發,工廠里如同隊列執行的單條流水線,其本質也是大并發。相比于并行,并發在理論上更先進,在實現上卻更簡單。
對并發的靈活應用,讓福特汽車在1913年就架設了自己的生產流水線,然后將汽車裝配速度一下子提高了8倍,創造了駭人的每10秒就有一臺T型車下線的記錄。
重新回到計算機技術上來,我們知道JavaScript是典型的單線程腳本語言,可是基于JavaScript的NodeJS的最大優勢之一卻是“超強的高并發能力”。
也就是單線程不但可以實現并發,在實際應用中還是被用來實現“高并發”的利器,因為它可以同時結合單線程對服務器資源的低要求和“異步”任務互不影響導致的事實上的“并發”這兩個優勢。