servlet_13

看上去這樣做似乎不是很合理,有這種感覺吧?這麼多的請求公用一個對象?至於爲什麼可以這麼做,那麼就得了解java多線程和java內存模型了。就是JVM對java線程是如何管理的,內存是如何分配的。這樣就又深了,我也並不是很清楚,但是我會盡量把它說清楚些,呵呵,好同情你,看這些帖子的人要有何等的耐心呢?
J2EE框架有一個很好的優點,就是已經實現了面對客戶端的多線程機制,你開發J2EE項目基本上不用怎麼管。但是你如果不知道的話,如何能編出好的Servlet代碼呢?說到這裏,又多說一句,如果你沒有任何的編程基礎,開始就只學java的話,雖然也會學的很好,但是你會失去代碼的基本內涵。是,java是拋棄了app層面的指針地址操作,安全了,簡單了,但是作爲一個app的開發人員不知道內存機制,那怎麼可能寫的出好的代碼呢?所以學c++吧,學了c++,java不用學,自然上手。在這裏力挺王亞少老師程序開發環境那門課的前四關於c++的節課,一定要好好的上好那4次課啊,絕對的深層次啓蒙。學語言不是從語法開始的,而是從字的構造開始學的,還記得小學一年級學的比較多的是什麼麼?不是較你認識很多的字,而是主要較你學上下結構,左右結構,和聲形字,象形字等等。

接着說,每個客戶端請求,都會自動產生一個新的java線程來處理這個請求。那麼一個java線程又是什麼概念呢?我也說不來,但是可以從內存管理來理解這個概念。java的內存管理。如果你看了前面關於java的介紹,應該知道JVM的內存管理是什麼個玩意了,就是JVM的管理機制加上物理內存的結合。這樣,自然有一個問題,相比操作系統本身的內存管理而言,JVM的內存管理肯定是不成熟的。

我們還是來看看JVM的內存管理吧。jvm把它的內存管理下的內存稱爲運行時數據區,包括方法區,堆,Java棧,PC寄存器,本地方法棧。這個結構的劃分基本上可以把java對內存的需求劃分清楚了。方法區主要放類的類型數據,就是加載java類的時候放的,關於類型數據的構成,在這裏就不深入了,它和class文件是對應的,內容也大部分相同。堆是放對象的,就是實例化一個類了。那麼到底是什麼呢?就是爲類的類變量分配內存。因爲某個對象是類的對象,所以這對象這邊要保存着它對應的類的類型數據的引用。也就是一個指針或說地址。

上面兩個內存塊是所有線程都共享的。對於方法區的線程共享很好理解,就是某個線程需要用到某個類,那它總得對類的類型數據可見。堆也還好理解,因爲對象本身就是可以讓各個線程共享的。這裏面有關於互斥等處理,這裏就不講。這一塊也稱爲主內存。

下面就是java棧和PC寄存器和本地方法棧了。每一個線程都有自己的Java棧和PC寄存器。本地方法棧就要看線程需不需要了,需要就有。這裏面的需要看線程中是否直接調用了本地方法而言的,在前面說過,java是通過javaAPI來和本地方法交互的,但是java也可以直接和本地方法交互,如果java代碼中直接調用了本地的某個鏈接庫,就是直接調用了本地方法,這個要另外處理的,因爲本地方法的地址已經不歸JVM管了,它已經管不到了。

那麼,看看Java棧,Java棧就是存放了該線程用到的局部變量,因爲是局部變量,所以用棧,用完就彈掉。所以這個棧一般又要分爲變量棧和操作棧,具體的就不講了。每個棧又分很多的棧幀,每個方法調用都分配一個棧幀。這一塊也稱爲工作內存。

那麼工作內存要和主內存交互啊,也就是你或許要在某個方法裏面設置類變量的值。這裏會爲工作內存分配一個主內存的緩存,就是那些類變量先緩存在工作內存中,改變後就會寫回主內存。

上面的這些,既說明了線程之間是可以共享某個對象的,同時也暗示了問題,就是互斥問題了,每個線程的工作內存都保留着主內存中類變量的緩存,大家都可以改,然後都會寫會主內存中,而當線程再去調用主內存裏面的類變量的值的時候,那如何保證是自己的緩存寫回去的值呢?很有可能是其他線程寫回去的值啊。這個問題就是Servlet初期的時候一個蠻大的問題,所以才會出來一個Servlet的singlethread模式,就是服務器端的Servlet每次只處理一個請求,處理完了再處理下一個。問題是解決了,但是卻帶了更大的問題,就是那麼的客戶端請求,難道都等着?完全的忽視了java的多線程機制的優勢。於是這個模式馬上就被拋棄了,後來又提出可以用javaAPI提供的互斥對象來操作,就是synchronized這個詞,如果學過操作系統高級教程,就應該對互斥問題非常瞭解的。就是這個詞可以讓操作同步,把設置類變量的值和引用類變量的值放到一起執行,其他用到這個對象的線程必須等着。這種方法呢?同樣讓性能大大的降低了,和前面那個相比較,就是一個是全面的等,一個是局部的等。到後來,人們開始從Servlet本身入手,解決問題不入逃避問題,所以就建議大家儘量妥善處理Servlet中的類變量的問題了,不是說不可以用,而是你用,但是儘量避免發生上面的問題。當然,實在是會遇到這個問題,就可以使用synchronized這個詞了。

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