2017-02-09 208 views
1

這個問題已經在我腦海中持續了好幾天。對於許多用戶訪問網站的基於客戶的Web應用程序,我是否需要所有後端Java類都是線程安全的?例如,如果我的web應用程序被100個客戶訪問,請求中的每個請求是否在jvm中分配了一組java對象?我正在開發一個Web項目,其中沒有任何類是同步的,我想知道多個http請求如何不共享同一個對象?web應用程序中的線程安全

+0

通常在Web應用程序中,您只想共享/全局化只讀對象。至於你的類和類,你只想同步你的類,如果他們實際上在請求之間共享。在請求期間創建和放棄的對象不應該同步添加到它們。 – RayfenWindspear

+1

作爲示例,在請求結束時,在請求中使用new/factory創建的任何Object超出範圍的對象完全是該請求的本地對象。通常,共享的任何其他內容都是從數據庫中存儲/讀取的,或者是隻讀全局數據。 – RayfenWindspear

+1

這取決於你的意思。請求之間唯一的共享對象通常是隻讀屬性(配置設置)。每個請求都可以被看作與所有其他請求隔離開來,沒有什麼需要跨請求共享。 – Pali

回答

3

典型的Web應用程序具有對象,如servlet,控制器,服務和數據訪問對象,它們沒有對話狀態,因此可以從併發線程安全地訪問。然後是由請求線程創建的持久化實體,通常不會傳遞給其他線程,它們的作用域僅限於創建它們的線程。

有一些基礎結構對象,如連接池和Hibernate會話工廠,需要設計爲線程安全。但是,如果你使用任何一種合理的框架,你通常不必自己創建這些類型的東西。

假設您設法避免在諸如服務或控制器之類的事情中不恰當地保持狀態,可能會導致數據庫操作以無意的方式交錯,這是由於開發人員不知道如何使用交易。這就是我想要的。所以三樣東西:

1)避免會話狀態的服務,控制器,DAOS,

2)使用框架(春天是一個例子),提供經過驗證的線程安全的基礎設施,並

3)瞭解數據庫事務和隔離級別以及樂觀鎖定,並使用它們來確保數據被不同線程訪問或更改而不會損壞。

0

取決於您的Web應用程序的目的和正在處理的對象。如果您的Web應用程序只是一個簡單的工具,那麼您可以將所有對象和其他數據保留在範圍內,並且您不需要擔心線程安全性。

一個在線計算器或一個豬拉丁翻譯器將是不需要擔心線程安全的工具的例子。

一旦開始處理持久數據並且對這些數據的併發訪問,您需要開始考慮線程安全以及可能發生的併發問題。

用戶正在檢查庫存水平並進行購買的在線商店將是一個需要某些線程安全性(假設數據存儲在應用程序中)的應用程序示例。你不能讓一個線程(用戶)嘗試和檢索一個項目,而另一個線程正在迭代它,試圖找到另一個。與使用靜態內存來存儲字符串的商店相比,緩存將是一個更好的例子。

在您的示例中,100個用戶正在訪問您的應用程序,每個客戶將訪問您的應用程序的單獨實例。這意味着他們發佈/接收的數據被隔離到他們與應用程序的交互中,並且對數據的任何更改都將保存在本地。如果您希望用戶從共享源發佈/獲取數據,那麼您需要了解如何執行線程安全性和確保併發性。

要更明確地回答您的問題;

如果您沒有任何存儲數據的靜態容器類型,則不需要擔心線程安全。這是因爲線程之間沒有共同的交互。

如果你有一個用於存儲數據的靜態容器類型,那麼很可能你需要考慮線程安全以確保所有線程都可以安全地訪問數據。

+0

您正在討論關於SQL事務隔離級別的更多信息,而不是併發性......並且這不是答案 – Pali

+0

如果您使用靜態HashMap或List來存儲對象,那麼您需要了解線程安全性和併發性問題。 – Afterfield