为什么java抗并发_用最通熟易懂的话说明,为什么要使用java并发编程
老早之前的計算機只有一個處理器,而 一個處理器在同一時刻只能處理一條指令 ,換句話說,我們的代碼需要一行一行的按順序被計算機執行,計算機只能把一個程序完整的執行完,然后再執行第二個程序。所以計算機專業的同學們要排隊去機房做實驗,一個人執行完然他的程序后,第二個人再執行自己的程序,這也就意味著 所有計算機資源是被一個程序獨占的 ,計算機資源包括處理器、內存、硬盤、輸入/輸出設備啥的。這樣的計算機系統我們稱之為 裸機 。
簡單批處理系統
后來人們發現對于價格高昂的計算機設備來說,在換人的過程中就浪費了好多時間,時間就是金錢,有這些時間可以多執行好多程序了。所以有人寫了一個程序,把所有同學們需要做實驗的程序都放在這個程序里排個隊,由這個程序來協調各個同學們的程序執行,一個執行完了立即換成另一個,這樣就不用人工干預了,所以他們把這樣的系統叫做 簡單批處理系統 ,而那個負責協調各個童鞋們程序的程序,就是所謂的 操作系統 的雛形。
多道批處理系統
我們知道,處理器的速度是嗖嗖的,比內存訪問的速度快好多個數量級,而內存又比硬盤、打印機等 I/O 設備啥的快好多個數量級,而程序執行過程中又免不了從硬盤里讀個文件,往打印機輸出個啥的,所以 處理器浪費了好多時間等待這些I/O操作的完成 。再一次,時間就是金錢,為了盡可能的剝削計算機的運算能力,在程序遇到 I/O 操作或者什么其他會阻塞程序執行的操作時,處理器會轉向執行其它的程序,什么時候這個阻塞的操作完成了,再掉過頭繼續執行它。從宏觀上看, 處理器可以各個程序輪流執行,所以這樣的系統就稱為 多道批處理系統 。
分時處理
有的同學對排隊執行程序這個事兒很有意見,大家都是學生,憑啥先執行你的后執行我的,你要是寫了個 while(true) ,那大家都得玩兒完~所以人們給 每個程序都分配一點處理器時間去輪流執行,每個程序分配到的執行時間就叫做 時間片 ,這個過程也叫做 分時處理 。又因為處理器速度太快了, 時間片 的大小可以做到微秒毫秒的大小,所以這個切換的過程對于人來說根本感覺不出來, 所以看起來像各個程序在同時執行 。不過后來人們在一臺計算機上又裝了多個處理器,就是我們常聽說的 4核 、 8核 啥的,所以也可能真正的在同時執行。
而 時間片 具體設置為多大,處理器怎么切換各個程序的執行,這些工作就是所謂的 操作系統來控制的。
進程
進程的概念和特點
我們自己寫的程序,也就是所謂的 用戶程序 是由操作系統來管理的,人們把一個 執行著的程序 叫做一個 進程 (英文名: Process ),每個 進程 都有這么兩個特點:
資源所有權
程序在運行過程中需要一定的資源,比如內存、 I/O 啥的,這些東西不能在不同進程間共享,假如一個進程占了另一個進程的內存,那另一個進程的數據不就丟失了么;一個進程正在使用打印機輸出東西,另一個進程也使用的話,不就尷尬了么。所以進程所擁有的這些資源是不能共享的,而這種資源分配的活是由 操作系統 來管理的。
調度/執行
操作系統 會為它管理的進程分配 時間片 ,來調度哪個進程應該被處理器處理,哪個應該先休息一會兒。
所以我們現在電腦里每個運行著的程序都是一個進程,可以打開你的任務管理器( windows )或者活動監視器( mac ),看到我們的電腦里其實有好多好多進程喔,什么QQ、微信、音樂播放器、視頻播放器啥的。
進程的狀態
在操作系統級別上,進程根據它運行的情況,可以分成下邊5種狀態 :
新建
剛剛創建的那個時刻, 操作系統 會為這個進程在內存中創建相應的數據,比如分配這個進程的ID,優先級什么的~這個狀態持續的時間比較短。
就緒
一旦該進程相關的一些數據創建好了,這個進程就會被放在一個叫 就緒隊列 的隊列里,之后操作系統就會從這個隊列里挑一個進程放到處理器里執行。
運行
這個進程被 操作系統 分配了時間片,處理器開始執行它。
阻塞
在執行進程的過程中,可能遇到某些阻塞的動作,比如 I/O 操作,處理器如果一直等待該阻塞動作完成的話就太浪費時間了,所以會把等待阻塞動作完成的進程放到一個叫 阻塞隊列 的隊列里,之后并不會從這個隊列里挑選即將執行的進程,而是直到該阻塞動作完成,才重新把該進程放到 就緒隊列 里等待執行。
退出
該進程執行完畢,或者遇到了什么錯誤,或者操作系統就是想弄死它,它就被殺死了,這個狀態里操作系統可能還會記錄一下死因啥的,這個過程也很短。
這些狀態的具體轉換過程看下圖:
串行編程和并行編程
到目前為止,我們的編程模式都是 串行編程 ,也就是處理器執行完一條指令再執行另一條。舉個例子啊,比如你媽給你布置了兩個 任務 :一是去打瓶醬油,二是去燒一壺水,按照 串行編程的方式就是兩個任務依次進行,也就是說你先打醬油,然后回來再燒水。這么做沒啥問題,但是沒有效率啊,所以你也可以先把水燒上,然后去打醬油,回來正好水燒開了~這種 多個任務同時進行的編程方式就叫做 并行編程 。
回到計算機中來, 串行編程 的方式就是我們把所有要完成的任務放到一個 進程 中去執行,而 并行編程 的方式就是我們去開幾個 進程 同時執行(注:這個 同時 可能是假的,如果只有單個處理器,那就是看上去是 同時 的)。這種 并行編程 的優勢是顯而易見的:
充分利用多個處理器
現代計算機的處理器越來越多,不用白不用。如果所有的任務都塞到1個進程中,而計算機實際有100個處理器,那么將會有99%的計算能力將被浪費。
防止任務的阻塞
即使是在單個處理器中,為多個任務創建多個進程也是有好處的。先執行的任務可能會需要執行某些 I/O 操作而造成阻塞,所以就需要等待 I/O 操作完成才能繼續執行。但是如果為每個任務創建一個進程之后,一個任務阻塞掉并不會影響別的任務的正常執行。
簡化編程的模型
把一個大任務拆分成若干個小任務自然是會事情清晰許多(注:也不是絕對啊),也就是所謂的大事化小,小事化了~所以把各個任務分配到不同進程里去執行在我們編程方面也會容易一些(注:不是絕對啊)。
線程
線程的概念
進程 是個好東西,可以給每個任務都分配一個進程以達到并發執行的目的。可是運行了一段時間人們發現還是有一些不好的地方的:
不同進程之間的資源不能夠共享。
這個對于為了一個大目標細分成的若干小任務很不友好。比方說對于一個網站來說,針對每一個訪問網站的連接都去創建一個進程,如果我們想累加一下總的訪問連接數就比較麻煩了,因為各個進程不能去修改同一塊內存。
創建、切換、銷毀進程成本太大。
小貼士: 由于我們的主題是java語言里的并發操作,至于操作系統底層對于創建、切換、銷毀進程都要做哪些東西不是我們嘮叨的范圍,但是這些操作的開銷真的很大,你知道這一點就好了~
再返回頭來看 進程 的兩個特點,一是對資源的所有權,二是可以作為操作系統調度和執行的單位,這兩個特點是沒有關系的,也就是說獨立的,現代的好多操作系統已經把這兩個特點給拆開了, 可以被調度和執行的單位通常被稱作 線程 或者 輕量級進程 ,而擁有資源所有權的單位通常被稱為 進程 。
小貼士: 由于歷史原因,原先的`進程`既是資源的分配單位,也是調度和執行的單位,所以我們打開一個程序就相當于打開一個進程。 提出`線程`概念之后,這種`打開一個程序就相當于打開一個進程`的叫法也被保留了下來。其實現在打開一個程序的意思是`打開一個進程并且打開若干個于這個進程相關聯的線程`。
線程的特點
看一下這個 線程 的各種特點
一個進程至少對應一個線程
操作系統每開始執行一個程序,都會為其分配所需的資源以及創建若干個 程序執行流 ,也就是說會創建一個線程以及若干線程。
各個 線程 可以共享同一個進程中的各種資源
因為 線程 是從屬于某個進程,所以進程中的內存、 I/O 啥的資源這個 線程 都可以訪問到。接著上邊那個例子,我們可以對于每一個連到網站的連接都可以分配一個線程,然后在申請一塊兒內存表示連接數,每創建一個線程都把連接數加1,問題就愉快的解決了。
創建、切換、銷毀線程的成本遠低于原先進程的成本
因為只是一個調度和執行的單位,本來就是原先進程概念的一部分,所以創建、切換、銷毀線程的成本就小多了。
線程通信比進程通信的效率高
原先進程間通信需要配合各種機制,現在線程間由于可以共享內存,所以通信就easy多了。
小貼士: 至于進程間需要啥機制我這就不說了,不是我們討論的范圍。
所以 線程 的提出完美的解決了一開始提出的把不同任務分配給不同進程執行的缺陷,現在我們可以把不同的任務分配給不同的 線程 去執行,不僅可以方便通信交流,而且創建和使用的成本還低~
線程的狀態
由于線程只是單純的繼承了線程中調度和執行的特性,所以原先進程擁有的狀態,現在線程一樣擁有,也就是: 創建 、 就緒 、 執行 、 阻塞 、 退出 。
總結
以上是生活随笔為你收集整理的为什么java抗并发_用最通熟易懂的话说明,为什么要使用java并发编程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微信空白网名126个
- 下一篇: hpux oracle9,oracle