使用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中。 但是,此解决方案具有以下缺点:

  1. 每当通过与上述相同的方法将任何值添加到会话中时,任何正在访问当前会话的线程都将阻塞。 当两个线程尝试访问不同的会话值时,也会发生这种情况。 这将使应用程序的限制更加严格。
  2. Servlet API实现可能选择实现HttpSession而不是一个单例实例。 在这种情况下,整个同步将失败。 (但是,这不是Servlet API的常见实现。)

最好找到要与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来实现。

参考: My日常Java博客中的JCG合作伙伴 Rafael Winterhalter提供的Guava , 用于并发应用程序的基于对象的微锁定 。

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/365674.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java cpu过高排查_涨薪秘籍:JAVA项目排查cpu负载过高

背景我负责的其中一个项目在空负载的情况下&#xff0c;CPU占用率依然保持着100%左右&#xff0c;线上、测试、开发的服务都一样&#xff1b;是什么导致的呢&#xff1f;在开发环境我查看了请求流量&#xff0c;这个流量可以忽略但CPU占用率一直在60%-100%之间浮动。分析问题流…

理财app说明

cordova库和魔蝎库使用的比较多 另外一个使用比较多的就是腾讯的youtu的第三方库&#xff0c;友盟的app统计的功能也有用 推送上使用的有激光推送、魅族推送、小米推送 另外多任务处理方面&#xff0c;有使用blots的库转载于:https://www.cnblogs.com/istar/p/9673249.html

巧用css的border属性完成对图片编辑功能的性能优化

一、需求场景&#xff1a; 最近闲来无事&#xff0c;boss提出了一个要求&#xff0c;研究相关代码并完成一个关于编辑图片功能的性能优化&#xff0c;该功能的主要界面展示如下&#xff1a; 通过了几分钟的短暂试用&#xff0c;发现就是一个简单的裁剪并保存用户选择并上传的图…

『Balancing Act 树的重心』

树的重心 我们先来认识一下树的重心。 树的重心也叫树的质心。找到一个点,其所有的子树中最大的子树节点数最少,那么这个点就是这棵树的重心,删去重心后&#xff0c;生成的多棵树尽可能平衡。 根据树的重心的定义&#xff0c;我们可以通过树形DP来求解树的重心。 设\(Max_i\)代…

求数的绝对值一定是正数_人教版初中数学七年级上册绝对值公开课优质课课件教案视频...

绝对值&#xff08;习题课&#xff09;导学案&#xff08;教师版&#xff09;【教学目标】1、能利用绝对值的性质求值。 2、通过复习绝对值&#xff0c;让学生对绝对值的理解更加深透。 3、通过复习&#xff0c;让学生掌握利用绝对值的代数和几何意义&#xff0c;并学会灵活运用…

使用Java EE安全性和JBoss AS 7.x保护JSF应用程序的安全

企业应用程序的常见要求是在登录页面后面保护所有JSF页面。 有时&#xff0c;您甚至希望在应用程序内部具有保护区&#xff0c;只有拥有特定角色的用户才能访问这些保护区。 Java EE标准附带实现受某些安全性约束保护的Web应用程序所需的所有方法。 在此博客文章中&#xff0c;…

java 十六进制转十进制_JAVA知识-分析JAVA中的重点和难点

Java中有很多内容在开发项目的过程中并不常用&#xff0c;但是却是很重要的部分&#xff0c;为了避免忘记&#xff0c;今天重新温习了一遍Java中的重点和难点&#xff0c;借此机会记录一下方便以后查找。本文主要分为以下几个部分&#xff1a;1.进制的相互转换2.Java中位运算符…

java运算符知识整理

赋值运算符: int a 0;a 2;System.out.println("a0"""".."a);int b 0;b2;System.out.println("b0""b2"".."b);int c 0;c-2;System.out.println("c0""c-2"".."c);int d 1;d*2;S…

开放才能进步!Angular和Wijmo一起走过的日子

Angular 已成为广受欢迎的前端框架。去年9月份&#xff0c;期待已久的 Angular2 的正式版发布之后&#xff0c;Angular 又迎来了新一轮热潮。伴随着 Angular 这一路走来&#xff0c;Wijmo 一直都是第一个全面支持各种版本 Angular 的JS控件库&#xff0c;为 Angular 用户提供着…

windows 检查cuda安装_Windows云主机GPU驱动-CUDA安装使用

IE安全相关配置如果打开浏览器无法正常下载&#xff0c;则需要设置Internet Explorer增强的安全配置。设置如下&#xff1a;打开"服务器管理器";点击"本地服务器"&#xff1b;"IE增强的安全配置"&#xff1b;选择"关闭"&#xff1b; 之…

镜像镜像–使用反射在运行时查看JVM内部

开发人员&#xff1a;Takipi会告诉您何时新代码在生产中中断– 了解更多 我们都习惯于在我们的日常工作中直接或通过利用反射的框架来运用反射。 它是Java和Scala编程的主要方面&#xff0c;它使我们使用的库可以与我们的代码进行交互&#xff0c;而无需对其进行硬编码的知识。…

UnicodeMath数学公式编码_翻译(Unicode Nearly Plain - Text Encoding of Mathematics Version 3)

目录 完整目录1. 简介2. 编码简单数学表达式2.1 分数2.2 上标和下标2.3 空白&#xff08;空格&#xff09;字符使用3. 编码其他数学表达式3.1 分隔符强烈推荐本文简明版UnicodeMath编码教程 本文为UnicodeMath官方文档的翻译&#xff0c;原文看这。翻译如有不准还请谅解&#x…

antd 表格树如何展开_如何分析工作,找出规律,使用excel大幅度提高工作效率...

在职场中&#xff0c;掌握一定的excel知识&#xff0c;有时候可以极大的提高工作效率&#xff0c;减少加班次数。但是有的人可能不知道如何去做&#xff0c;下面我使用一个我前几天遇到的工作场景&#xff0c;一步一步的来给大家展示一下&#xff0c;如何使用excel提高工作效率…

eclipse插件 tcp/iip monitor

http://huangrongyou.iteye.com/blog/1764041 转载于:https://www.cnblogs.com/chyxOne/p/9673784.html

Wijmo 更优美的jQuery UI部件集:复合图表(CompositeChart)

Wijmo的CompositeChart控件允许您使用一个Chart来分析和展现复杂的数据。相同的数据可以使用不同的可视化效果&#xff0c;不同的图表类型展现在一个图表内&#xff0c;使得用户可以从不同的角度&#xff0c;了解分析这组数据所表达的内容 。 本文将介绍如何使用Wijmo的Composi…

广联达2018模板算量步骤_广联达gtj2021实操案例,新增6大板块,快速提高算量效率...

对于从事造价行业的朋友来说&#xff0c;广联达软件是我们最经常用到的软件&#xff0c;不仅是因为广联达软件能够在提高工作效率&#xff0c;主要还是现在大数据下&#xff0c;广联达软件可以做到更精准、零失误广联达软件更新的也比较快&#xff0c;广联达GTJ2021版已经更新出…

鲜为人知的Java 8功能:广义目标类型推断

遍历Java 8功能列表 &#xff0c; 广义目标类型推断使我震惊&#xff0c;因为它是一个特别有趣&#xff0c;鲜为人知的瑰宝。 看起来Java语言设计人员将减轻过去使用泛型&#xff08;Java 5-7&#xff09;时遇到的某些痛苦。 让我们看看他们的例子&#xff1a; class List<…

谈谈技术原则,技术学习方法,代码阅读及其它

一、选用技术的原则比较规范的软件开发过程要到有限的几个公司才能学到。偶现在所采用的方法都是圡方法&#xff0c;主程序员&#xff0c;测试驱动&#xff0c;文档和代码写在一起&#xff0c;原型。但基本上坚持几个原则&#xff1a;在工作上以实用为主导&#xff0c;哪个实用…

python下载库报错_下载python中Crypto库报错:ModuleNotFoundError: No module named ‘Crypto’的解决...

前言最近在网上找了很多下载Crypto的方法&#xff0c;感觉作用都不算很大&#xff0c;然后自己瞎搞瞎搞就搞好了&#x1f605;&#xff0c;所以打算分享出来。直接pip下载或者Anaconda下载&#xff0c;Anaconda的话可以直接在官网上下载&#xff0c;pip就不说了&#xff0c;下载…

WPF中元素拖拽的两个实例

WPF中元素拖拽的两个实例 原文:WPF中元素拖拽的两个实例今天结合之前做过的一些拖拽的例子来对这个方面进行一些总结&#xff0c;这里主要用两个例子来说明在WPF中如何使用拖拽进行操作&#xff0c;元素拖拽是一个常见的操作&#xff0c;第一个拖拽的例子是将ListBox中的子元素…