日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

使用Guava对并发应用程序进行基于对象的微锁定

發(fā)布時(shí)間:2023/12/3 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用Guava对并发应用程序进行基于对象的微锁定 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

編寫并發(fā)Java應(yīng)用程序時(shí)最令人討厭的問題之一是對(duì)線程之間共享的資源的處理,例如Web應(yīng)用程序的會(huì)話和應(yīng)用程序數(shù)據(jù)。 結(jié)果,如果應(yīng)用程序的并發(fā)級(jí)別很低,許多開發(fā)人員選擇根本不同步這些資源。 例如,不太可能同時(shí)訪問會(huì)話資源:如果請(qǐng)求周期在很短的時(shí)間內(nèi)完成,那么當(dāng)?shù)谝粋€(gè)請(qǐng)求周期仍在進(jìn)行時(shí),用戶不太可能使用第二個(gè)瀏覽器選項(xiàng)卡發(fā)送并發(fā)請(qǐng)求。 隨著Ajax驅(qū)動(dòng)的Web應(yīng)用程序的興起,這種信任方法的確變得越來越危險(xiǎn)。 在Ajax應(yīng)用程序中,例如,用戶可以在另一個(gè)瀏覽器窗口中啟動(dòng)類似任務(wù)時(shí),請(qǐng)求完成一項(xiàng)較長(zhǎng)時(shí)間的任務(wù)。 如果這些任務(wù)訪問或?qū)懭霑?huì)話數(shù)據(jù),則需要同步此類訪問。 否則,您將面臨細(xì)微的錯(cuò)誤,甚至?xí)龅桨踩珕栴},例如本博客文章中指出的那樣 。

Java的synced關(guān)鍵字是引入鎖的一種簡(jiǎn)單方法。 例如,此示例僅在需要將新實(shí)例寫入會(huì)話時(shí)才阻塞請(qǐng)求周期的線程。

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);

此代碼會(huì)將新的ShoppingCart實(shí)例添加到會(huì)話中。 每當(dāng)找不到購(gòu)物車時(shí),該代碼將獲取當(dāng)前用戶會(huì)話的監(jiān)視器,并將新的ShoppingCart添加到當(dāng)前用戶的HttpSession中。 但是,此解決方案具有以下缺點(diǎn):

  • 每當(dāng)通過與上述相同的方法將任何值添加到會(huì)話中時(shí),任何正在訪問當(dāng)前會(huì)話的線程都將阻塞。 當(dāng)兩個(gè)線程嘗試訪問不同的會(huì)話值時(shí),也會(huì)發(fā)生這種情況。 這將使應(yīng)用程序的限制更加嚴(yán)格。
  • Servlet API實(shí)現(xiàn)可能選擇實(shí)現(xiàn)HttpSession而不是一個(gè)單例實(shí)例。 在這種情況下,整個(gè)同步將失敗。 (但是,這不是Servlet API的常見實(shí)現(xiàn)。)
  • 最好找到要與HttpSession實(shí)例同步的其他對(duì)象。 但是,創(chuàng)建此類對(duì)象并在不同線程之間共享它們會(huì)帶來相同的問題。 避免這種情況的一種好方法是使用既固有并發(fā)又允許使用弱鍵的Guava緩存:

    LoadingCache<String, Object> monitorCache = CacheBuilder.newBuilder().weakValues().build(new CacheLoader<String, Object>{public Object load(String key) {return new Object();}});

    現(xiàn)在我們可以這樣重寫鎖定代碼:

    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緩存是自填充的,將僅返回一個(gè)Monitor Object實(shí)例,該實(shí)例可用作對(duì)共享會(huì)話資源的鎖定,該資源由shoppingCart普遍標(biāo)識(shí)。 Guava緩存由ConcurrentHashMap支持,該ConcurrentHashMap通過僅在映射鍵的哈希值存儲(chǔ)桶上進(jìn)行同步來避免同步。 結(jié)果,使應(yīng)用程序成為線程安全的,而不會(huì)全局阻止它。 另外,您不必?fù)?dān)心內(nèi)存用完,因?yàn)槿绻辉偈褂帽O(jiān)視器(和相關(guān)的緩存條目),則會(huì)被垃圾回收。 如果您不使用其他緩存,甚至可以考慮使用軟引用來優(yōu)化運(yùn)行時(shí)間。

    當(dāng)然可以完善這種機(jī)制。 例如,可以返回一個(gè)ReadWriteLock而不是返回Object實(shí)例。 同樣,在會(huì)話啟動(dòng)時(shí)實(shí)例化LoadingCache也很重要。 這可以通過例如HttpSessionListener來實(shí)現(xiàn)。

    參考: My日常Java博客中的JCG合作伙伴 Rafael Winterhalter提供的Guava , 用于并發(fā)應(yīng)用程序的基于對(duì)象的微鎖定 。

    翻譯自: https://www.javacodegeeks.com/2013/12/object-based-micro-locking-for-concurrent-applications-by-using-guava.html

    總結(jié)

    以上是生活随笔為你收集整理的使用Guava对并发应用程序进行基于对象的微锁定的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。