使用Guava对并发应用程序进行基于对象的微锁定
編寫并發Java應用程序時最令人討厭的問題之一是對線程之間共享的資源的處理,例如Web應用程序的會話和應用程序數據。 結果,如果應用程序的并發級別很低,許多開發人員選擇根本不同步這些資源。 例如,不太可能同時訪問會話資源:如果請求周期在很短的時間內完成,那么當第一個請求周期仍在進行時,用戶不太可能使用第二個瀏覽器選項卡發送并發請求。 隨著Ajax驅動的Web應用程序的興起,這種信任方法的確變得越來越危險。 在Ajax應用程序中,例如,用戶可以在另一個瀏覽器窗口中啟動類似任務時,請求完成一項較長時間的任務。 如果這些任務訪問或寫入會話數據,則需要同步此類訪問。 否則,您將面臨細微的錯誤,甚至會遇到安全問題,例如本博客文章中指出的那樣 。
Java的synced關鍵字是引入鎖的一種簡單方法。 例如,此示例僅在需要將新實例寫入會話時才阻塞請求周期的線程。
HttpSession session = request.getSession(true); if (session.getAttribute("shoppingCart") == null) {synchronize(session) {if(session.getAttribute("shoppingCart")= null) {cart = new ShoppingCart();session.setAttribute("shoppingCart");}} } ShoppingCart cart = (ShoppingCart)session.getAttribute("shoppingCart"); doSomethingWith(cart);此代碼會將新的ShoppingCart實例添加到會話中。 每當找不到購物車時,該代碼將獲取當前用戶會話的監視器,并將新的ShoppingCart添加到當前用戶的HttpSession中。 但是,此解決方案具有以下缺點:
最好找到要與HttpSession實例同步的其他對象。 但是,創建此類對象并在不同線程之間共享它們會帶來相同的問題。 避免這種情況的一種好方法是使用既固有并發又允許使用弱鍵的Guava緩存:
LoadingCache<String, Object> monitorCache = CacheBuilder.newBuilder().weakValues().build(new CacheLoader<String, Object>{public Object load(String key) {return new Object();}});現在我們可以這樣重寫鎖定代碼:
HttpSession session = request.getSession(true); Object monitor = ((LoadingCache<String,Object>)session.getAttribute("cache")).get("shoppingCart"); if (session.getAttribute("shoppingCart") == null) {synchronize(monitor) {if(session.getAttribute("shoppingCart")= null) {cart = new ShoppingCart();session.setAttribute("shoppingCart");}} } ShoppingCart cart = (ShoppingCart)session.getAttribute("shoppingCart"); doSomethingWith(cart);Guava緩存是自填充的,將僅返回一個Monitor Object實例,該實例可用作對共享會話資源的鎖定,該資源由shoppingCart普遍標識。 Guava緩存由ConcurrentHashMap支持,該ConcurrentHashMap通過僅在映射鍵的哈希值存儲桶上進行同步來避免同步。 結果,使應用程序成為線程安全的,而不會全局阻止它。 另外,您不必擔心內存用完,因為如果不再使用監視器(和相關的緩存條目),則會被垃圾回收。 如果您不使用其他緩存,甚至可以考慮使用軟引用來優化運行時間。
當然可以完善這種機制。 例如,可以返回一個ReadWriteLock而不是返回Object實例。 同樣,在會話啟動時實例化LoadingCache也很重要。 這可以通過例如HttpSessionListener來實現。
翻譯自: https://www.javacodegeeks.com/2013/12/object-based-micro-locking-for-concurrent-applications-by-using-guava.html
總結
以上是生活随笔為你收集整理的使用Guava对并发应用程序进行基于对象的微锁定的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 大型布线:Java云应用程序缺少的技术
- 下一篇: 镜片怎么取下来 去镜片的方法