第一章 走進java線程中的世界--《java多線程編程實戰指南-核心篇》

1.1 進程、線程和任務

進程是程序向操作系統申請資源(如內存空間和文件句柄)的基本單位。線程是進程中可獨立執行的最小單位。

一個進程可以包含多個線程。同一個進程中的所有線程共享該進程中的資源。

線程所要完成的計算就被稱爲任務,特定的線程總是在執行特定的任務。

1.2 多線程編程簡述

函數式編程中的函數是最基本抽象單元,面向對象編程中的類是最基本抽象單位,多線程編程中以線程爲基本抽象單位;實際上java平臺中的一個線程就是一個對象。

增加線程可能會增加單位時間內完成的任務量,即提高程序的計算效率;但它也可能降低程序的計算效率。

1.3 java線程API簡介

在java平臺中創建一個線程就是創建一個Thread類或其子類的實例,其run方法相當於線程的任務處理邏輯的入口方法,它由java虛擬機在運行相應的線程時直接調用,而不是由應用代碼進行調用。

運行一個線程實際上就是讓java虛擬機執行該線程的run方法,從而使線程的任務處理邏輯代碼得以執行。Thread類的start方法的作用是啓動相應的線程。啓動一個線程的實質是請求java虛擬機運行相應的線程,而這個線程具體何時能夠運行是由線程調度器決定的。因此,start方法調用結束並不意味着相應線程已經開始運行,這個線程可能稍後纔會被運行,甚至可能永遠不會被執行。

運行結束的線程所佔用的資源(如內存空間)會如同其他java對象一樣被java虛擬機垃圾回收。線程是一次性用品,不能重複調用start方法使其重新運行,start方法只能調用一次。

java中一個線程就是一個對象,對象的創建離不開內存空間的分配。創建一個線程與創建其他類型的java對象所不同的是,java虛擬機會爲每一個線程分配調用棧所需的內存空間。調用棧用於跟蹤java代碼間的調用關係以及java代碼對本地代碼的調用。另外,java平臺中的每個線程可能還有一個內核線程與之對應。因此創建線程對象比創建其他類型的對象成本要高一些。

關於創建Thread類實例還是創建Runnable接口:1.一個是基於繼承的技術,一個是基於組合的技術;2.創建Runnable實例意味着多個線程可以共享一個Runnale實例;3.創建成本上,java中的線程實例是一個特殊的Runnable實例,因爲在創建它的時候java虛擬機會爲其分配調用棧空間、內核線程等資源。因此,創建一個線程實例比創建一個普通的Runnable實例來說,成本相對高昂一些。

線程包含編號、名稱、線程類別和優先級四個屬性。關於線程類別:分爲守護線程和用戶線程,用戶線程會組織java虛擬機的正常停止,即一個java虛擬機只有在其所有用戶線程都運行結束的情況下才能正常停止,而守護線程則不會影響java虛擬機的正常停止,即應用程序中有守護線程在運行也不影響java虛擬機的正常停止;關於線程優先級:java線程的優先級使用不當或者濫用則可能導致某些線程永遠無法得到運行,即產生線程飢餓。

Thread類的常用方法:

1.4 線程的層次關係

線程A所執行的代碼創建了線程B,那麼線程B是線程A的子線程,線程A是線程B的父線程。

1.5 線程的生命週期狀態

NEW:一個已創建而未啓動的線程處於該狀態。由於一個線程實例只能夠被啓動一次,因此一個線程只可能有一次處於該狀態。

RUNNABLE:該狀態可被看成一個複合狀態。它包括兩個子狀態:READY和RUNNING。前者標識處於該狀態的線程可以被線程調度器進行調度而使之處於RUNNING狀態。後者表示處於該狀態的線程正在運行,即相應線程對象的run方法所對應的指令正在由處理器執行。執行Thread.yield()的線程,其狀態可能會由RUNNING轉換爲READY。處於READY子狀態的線程也被稱爲活躍線程。

BLOCKED:一個線程發起一個阻塞式I/O操作後,或者申請一個由其他線程持有的獨佔資源時,相應的線程會處於該狀態。處於BLOCKED狀態的線程並不會佔用處理器資源。當阻塞式I/O操作完成後,或者線程獲得了其申請的資源,該線程的狀態有可能轉換爲RUNNABLE。

WAITING:一個線程執行了某些特定方法之後就會處於這種等待其他線程執行另外一些特定操作的狀態。能夠使其執行線程變更爲WAITING狀態的方法包括:Object.wait()、Thread.join()和LockSupport.park(Object)。能夠使相應線程從WAITING變更爲RUNNABLE的響應方法包括:Object.notify()/notifyAll()和LockSupport.unpark(Object)。

TIMED_WAITING:該狀態和WATING類似,差別在於處於該狀態的線程並非無限制地等待其他線程執行特定操作,而是處於帶有時間限制的等待狀態。當其他線程沒有在指定時間內執行該線程所期望的特定操作時,該線程的狀態自動轉換爲RUNNABLE。

TERMINATED:已經執行結束的線程處於該狀態。由於一個線程實例只能被啓動一次,因此一個線程也只可能有一次處於該狀態。Thread.run()正常返回或者由於拋出異常而提前終止都會導致響應線程處於該狀態。

一個線程在其整個生命週期中,只可能有一次處於NEW狀態和TERMINATED狀態。

1.6 多線程編程的優勢和風險

優勢:1.提高系統吞吐率;2.提高響應性;3.充分利用多核處理器資源;4.最小化系統資源的使用;5.簡化程序結構,線程可以簡化複雜應用程序的結構;

風險:1.線程安全問題;2.線程活性問題(某些線程一直處於等待其他線程釋放鎖狀態,即產生死鎖;一個線程在嘗試某個操作但就是無法緊張,即產生活鎖);3.上下文切換;4.可靠性;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章