java 程序、執行緒
程序是作業系統中執行的一個任務(一個任務程式執行在一個程序中),如一個qq程式就是一個程序。程序是一塊包含了某些資源的記憶體區域,作業系統利用程序把它的工作劃分為一些功能單元,這些功能單元就稱為程序。程序還擁有一個私有的虛擬地址空間僅能被它所包含的執行緒訪問。執行緒只能歸屬於一個程序且只能訪問該程序擁有的資源。當作業系統建立一個程序後,該程序會自動申請一個名為主執行緒或首要執行緒的執行緒。
一個執行緒是程序的一個順序執行流,同類的多個執行緒共享一塊記憶體空間和一組系統資源,執行緒本身有一個供程式執行時的堆疊。執行緒在切換時負荷小,因此執行緒也被稱為輕負荷程序,一個程序可以包含多個執行緒。
程序與執行緒的區別:一個程式至少有一個程序,一個程序至少有一個執行緒。執行緒的劃分尺度小於程序,使得多執行緒程式的併發性高,此外,程序在執行過程中擁有獨立的記憶體單元,而多個執行緒共享記憶體,從而極大提高了程式的執行效率。執行緒在執行過程中與程序的區別在於每個獨立的執行緒有一個程式執行的入口、順序執行序列和程式的出口。但是執行緒不能獨立執行,必須依存在應用程式中,由應用程式提供多個執行緒的執行控制。從邏輯角度來看,多執行緒的意義在於一個應用程式中,有多個執行部分可以同時執行,但作業系統並沒有將多個執行緒看做多個獨立的應用來實現程序的排程和管理以及資源分配。
執行緒通常用於在一個程式中需要同時完成多個任務的情況,將每個任務定義為一個執行緒,使這些任務一同工作。雖然一個程式也可用於單一執行緒中完成,但是使用多執行緒可以提高效率,比如下載檔案等。
然而,多個執行緒“同時”執行只是感官上的一種表現,事實上,執行緒是併發執行的,作業系統將時間劃分為很多時間片段(時間片),儘可能均勻的分配給每一個執行緒,獲取時間片段的執行緒被CPU執行,而其他的執行緒全部處於等待狀態,所以巨集觀上都在執行,但並不是絕對意義上的同時發生,即併發原理。
對於多執行緒的理解:看了一篇部落格,舉的例子很貼切,很生動,在此,借用一下。
假如你去一家餐館吃飯,那家餐館只有一個服務員,所以這個唯一的服務員給你點菜的時候,別的去餐館吃飯的人就得等著。但是如果這個餐館有多個服務員的話,那麼在同一時刻就可以給多個去餐館吃飯的人點菜,這裡舉A、B兩個服務員,分別接待甲、乙兩個顧客,而每個顧客點了不同的三道菜。
上面例子中的餐館可以理解成一個程式,而A、B兩個服務員可以理解成兩個執行緒,後廚做菜的廚師可以看做是CPU(假設只有一個CPU)。
從A、B兩個服務員同時接待甲、乙兩個顧客這個表象來看執行緒是“同步”、“併發”執行的,但是在廚師做菜的過程中還是有先後之分的,只是廚師會把甲乙兩個顧客點的菜分開來做,做完甲的一道菜後立刻開始做乙的一道菜,這樣不停地切換著做甲乙兩個顧客點的菜。而在甲乙顧客看來他們桌上都有著菜吃,誤以為他們的菜是同時做出來的。
而計算機裡的多執行緒也是如此,cpu會分配給每一個執行緒只有極少的執行時間,時間一到就交出執行權,所有執行緒被快速的切換執行,因為cpu的執行速度非常的快,所以在執行的過程中我們可以簡單的認為這些執行緒是“併發”執行的。
上面廚師做菜的原則是:不同的切換顧客們點的菜。假設廚師做菜的原則變了,是單顧客原則:給一位顧客做完所有的菜後再給別的顧客做菜,就是說先一下子把甲點的三道菜全做出來後再去做乙點的那三道菜,這樣的話如果廚師在做甲的某一道菜時發現甲點的那道菜的原料沒有了,那麼乙的菜就得一直等著。
如果是在計算機中,單顧客原則執行執行緒的話,當一個惡性的執行緒執行不下去時,計算機就會出現宕機的現象,這時候只能重啟。
上面介紹的廚師做菜的兩種原則分別代表著計算機中執行緒的兩種排程形式:搶佔式排程和非搶佔式排程。應用中我們一般用搶佔式排程(即廚師的第一種做菜原則)。