1. 程式人生 > >Struts2中action生命週期和Servlet生命週期

Struts2中action生命週期和Servlet生命週期

action生命週期
        每次請求到來時,都會建立一個新的Action例項
        action是執行緒安全,可以使用成員變數接收引數。

Servlet生命週期分為三個階段: 
            1:初始化階段,呼叫init()方法 
            2:響應客戶請求階段,呼叫service()方法 
            3:終止階段,呼叫destory()方法
        servlet存線上程安全問題:

1、Servlet物件是一個單例項的物件,並且在多執行緒的環境下執行,所以Servlet物件存線上程安全問題。

2、什麼情況下會存線上程安全問題?

條件1:多執行緒併發

條件2:有共享資料

條件3:共享資料涉及到修改操作

3、JVM包括三塊主要的記憶體空間:棧記憶體、堆記憶體、方法區記憶體  

 - 棧記憶體: 方法呼叫的時候,該方法所需要的記憶體在棧中分配,此時發生壓棧動作,方法結束的時候,給該方法在棧中分配的記憶體釋放,此時發生彈棧動作 一個方法的程式碼片段可以對應多個不同的記憶體空間。 一個執行緒會對應一個獨立的棧空間【100個執行緒有100個棧】 棧中主要儲存區域性變數,區域性變數的記憶體永遠都不會多執行緒共享,所以區域性變數不會存線上程安全問題。

- 堆記憶體: JVM堆記憶體空間只有一個,所以JVM堆記憶體在多執行緒環境下是共享的。 new出來的物件在堆中儲存。例項變數在物件內部。 所以例項變數可能在多執行緒環境下共享,可能存線上程安全問題。

- 方法區記憶體: JVM方法區記憶體只有一個,也是多執行緒共享的。 在方法區中存在靜態變數,所以靜態變數可能會存線上程安全問題。

4、Servlet是單例的,Servlet物件只有一個,多執行緒共享,所以Servlet中若存在靜態變數和例項變數,都可能存線上程安全問題, 但是Servlet的doGet/doPost方法內部的區域性變數不會存線上程安全問題。

5、怎麼解決執行緒安全問題?

選擇1:儘量使用區域性變數

選擇2:將單例改為多例

選擇3:若必須使用單例,可以使用執行緒同步機制synchronized

注意:執行緒同步機制是最後的選擇,這種方式會讓吞吐量降低,影響客戶的體驗