2017-08-06 30 views
1

我有一個訪問和修改存儲在servlet上下文中的對象「myBean」的servlet。是否顯式鎖定「myBean」與一個需要的同步塊或默認情況下維護?示例代碼:訪問servlet上下文中的對象時需要一個同步塊嗎?

public class StopFilesMergeServlet extends HttpServlet { 
     @Override 
     protected void doPost(HttpServletRequest req, HttpServletResponse resp) { 
      MYBean myBean = req.getServletContext().getAttribute("myBean"); 
      synchronized (myBean) { //is this necessary? 
       int oldValue = myBean.getProperty1(); 
       int newValue = oldValue + 10; 
       myBean.setProperty1(newValue); 
      } 
      ... 
      return; 
    } 
+0

我建議讓bean本身是線程安全的,可以從任何線程正常調用更高級的操作,而不是依賴於人們記住這個或那個東西需要在外部同步。並且請注意[TOCTTOU](https://en.wikipedia.org/wiki/Time_of_check_to_time_of_use)問題。 – biziclop

+0

根據答案讓bean線程安全是最好的解決方案。但是,我也存儲在ServletContext中的HashMap或其他集合呢? – Yaros

+0

也將它們包裝在線程安全的容器中。但是如果你發現自己在servlet上下文中存儲了很多可變數據(當然這在所有會話中都是共享的),這也會引起人們懷疑你真正的問題是架構。 – biziclop

回答

0

Spring並沒有做任何事情來保證bean的線程安全。

是否顯式鎖定需要同步塊的「myBean」或默認情況下是否維護?

您的意圖從您的示例中不清楚。如果你正在讀取一個bean的值,你需要顯式鎖定,比較它然後更新。如果狀態爲myBean,那麼更好的選擇是使線程安全。

+2

我不認爲在問題中甚至提到了Spring,儘管你的答案在技術上仍然正確:) – biziclop

+0

@biziclop ha。我必須使用太多的彈簧才能在任何地方看到它:) – goblinjuice

+0

@goblinjuice爲了更加清晰,我編輯我的示例。 – Yaros

相關問題