Java锁实现

我们都使用第三方库作为开发的正常部分。 通常,我们无法控制其内部。 JDK随附的库是一个典型示例。 这些库中的许多库都使用锁来管理竞争。
JDK锁具有两种实现。 人们使用原子CAS样式指令来管理索赔过程。 CAS指令往往是最昂贵的CPU指令类型,并且在x86上具有内存排序语义。 锁通常是无竞争的,这会导致可能的优化,从而可以使用避免使用原子指令的技术将锁偏向无竞争的线程。 这种偏向使得理论上的锁定可以被同一线程快速重新获得。 如果该锁最终被多个线程争用,则该算法将从偏见中恢复过来,并使用原子指令退回到标准方法。 偏向锁定已成为Java 6的默认锁定实现 。
在遵守单一作者原则时,偏向锁定应该是您的朋友。 最近,当使用套接字API时,我决定衡量锁定成本,并对结果感到惊讶。 我发现我的无竞争线程所产生的开销比我预期的要多。 我汇总了以下测试,以比较Java 6中可用的当前锁实现的成本。
考试
为了进行测试,我将在锁中增加一个计数器,并增加锁中竞争线程的数量。 对于Java可用的3种主要锁实现,将重复此测试:
  1. Java语言监视器上的原子锁定
  2. Java语言监视器上的偏向锁定
  3. Java 5中随java.util.concurrent包引入的ReentrantLock 。
我还将在最新的3代Intel CPU上运行测试。 对于每个CPU,我将执行测试,直到核心计数将支持的最大并发线程数为止。
该测试是在64位Linux(Fedora Core 15)和Oracle JDK 1.6.0_29上进行的。

编码

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.CyclicBarrier;import static java.lang.System.out;public final class TestLocks implements Runnable
{public enum LockType { JVM, JUC }public static LockType lockType;public static final long ITERATIONS = 500L * 1000L *1000L;public static long counter = 0L;public static final Object jvmLock = new Object();public static final Lock jucLock = new ReentrantLock();private static int numThreads;private static CyclicBarrier barrier;public static void main(final String[] args) throws Exception{lockType = LockType.valueOf(args[0]);numThreads = Integer.parseInt(args[1]);runTest(numThreads); // warm upcounter = 0L;final long start = System.nanoTime();runTest(numThreads);final long duration = System.nanoTime() - start;out.printf("%d threads, duration %,d (ns)\n", numThreads, duration);out.printf("%,d ns/op\n", duration / ITERATIONS);out.printf("%,d ops/s\n", (ITERATIONS * 1000000000L) / duration);out.println("counter = " + counter);}private static void runTest(final int numThreads) throws Exception{barrier = new CyclicBarrier(numThreads);Thread[] threads = new Thread[numThreads];for (int i = 0; i < threads.length; i++){threads[i] = new Thread(new TestLocks());}for (Thread t : threads){t.start();}for (Thread t : threads){t.join();}}public void run(){try{barrier.await();}catch (Exception e){// don't care}switch (lockType){case JVM: jvmLockInc(); break;case JUC: jucLockInc(); break;}}private void jvmLockInc(){long count = ITERATIONS / numThreads;while (0 != count--){synchronized (jvmLock){++counter;}}}private void jucLockInc(){long count = ITERATIONS / numThreads;while (0 != count--){jucLock.lock();try{++counter;}finally{jucLock.unlock();}}}
}

编写测试脚本:

设置-x
对于{1..8}中的i; 做Java -XX:-UseBiasedLocking TestLocks JVM $ i; 做完了 对于{1..8}中的i; 做Java -XX:+ UseBiasedLocking TestLocks JVM $ i; 做完了 对于{1..8}中的i; 做Java TestLocks JUC $ i; 做完了

结果

图1
图2
图3
在现代英特尔处理器上,偏置锁定不再应该是默认的锁定实现。 我建议您使用-XX:-UseBiasedLocking JVM选项来评估您的应用程序和实验,以确定是否可以从针对无竞争情况使用基于原子锁的算法中受益。

观察结果
  1. 在无竞争的情况下,有偏锁比原子锁贵10%。 似乎对于最近的CPU代来说,原子指令的成本比偏向锁的必要内务处理要少。 在Nehalem之前,锁定指令会在内存总线上声明一个锁定以执行这些原子操作,每条操作将花费100个以上的周期。 自Nehalem以来,原子指令可以在CPU内核本地进行处理,并且在执行内存排序语义时不需要等待存储缓冲区为空时,通常只需花费10-20个周期。
  2. 随着争用的增加,语言监视器锁定将Swift达到吞吐量限制,而与线程数无关。
  3. 与使用同步的语言监视器相比,ReentrantLock提供了最佳的无竞争性能,并且随着争用的增加,扩展性也显着提高。
  4. 当2个线程竞争时,ReentrantLock具有降低性能的奇怪特征。 这值得进一步调查。
  5. 当竞争线程数较少时,Sandybridge遭受原子指令增加的延迟 ,这在上一篇文章中已详细介绍。 随着竞争线程数的不断增加,内核仲裁的成本趋于占主导地位,而Sandybridge则显示出其在提高内存吞吐量方面的优势。
结论
在开发自己的并发库时,如果无锁替代算法不是可行的选择,则建议使用ReentrantLock而不是使用synced关键字,因为它在x86上具有明显更好的性能。
更新2011年11月20日
Dave Dice指出,未对JVM启动的前几秒中创建的锁实施偏向锁。 我将在本周重新运行测试并发布结果。 我收到了更多质量反馈,表明我的结果可能无效。 微型基准测试可能会很棘手,但是在大型应用中衡量自己的应用程序的建议仍然存在。
考虑到Dave的反馈,可以在此后续博客中查看测试的重新运行。
参考:来自我们的JCG合作伙伴 Martin Thompson的Java锁实现,来自Mechanical Sympathy Blog。

翻译自: https://www.javacodegeeks.com/2012/07/java-lock-implementations.html

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

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

相关文章

一键生成APP官网

只需要输入苹果下载地址&#xff0c;安卓市场下载地址&#xff0c;或者内测下载地址&#xff0c;就能一键生成APP的官网&#xff0c;方便在网上推广。 好推APP官网 www.hotapp.cn/app 转载于:https://www.cnblogs.com/likwo/p/6223889.html

python 字符ab+字符c 2_“ab”+”c”*2 结果是: (1.3分)_学小易找答案

【判断题】药物效应动力学简称药效学,是研究药物对机体的作用?【单选题】以下关于Python语言中“缩进”说法正确的是:‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪…

数据结构及算法 -- 目录

排序算法 -- 目录 啦啦啦转载于:https://www.cnblogs.com/ClassNotFoundException/p/7122848.html

Spring MVC集成测试

在Spring MVC中对控制器进行集成测试的一种方法是使用Spring提供的集成测试支持。 对于Junit4&#xff0c;此支持包括一个名为SpringJunit4ClassRunner的自定义Junit Runner和一个用于加载相关Spring配置的自定义批注。 样本集成测试将遵循以下原则&#xff1a; RunWith(Spri…

spark 快速入门 java API

Spark的核心就是RDD&#xff0c;对SPARK的使用入门也就是对RDD的使用&#xff0c;包括action和transformation 对于Java的开发者&#xff0c;单单看文档根本是没有办法理解每个API的作用的&#xff0c;所以每个SPARK的新手&#xff0c;最好按部就班直接学习scale, 那才是一个高…

网页设计上机考试原题_Dreamweaver上机考试题目dreamweaver试题库网页制作试题.doc...

网页设计上机考试题集注意&#xff1a;所有题目中涉及的素材都在考试文件夹内&#xff0c;其中图片在下面的pic文件夹中&#xff0c;音乐、flash在media文件夹。1) 在1.html中的顶部添加一个锚点链接&#xff0c;点击之能立即到达页面最底端。2) 将1.html中的所有链接的默认样式…

35数据结构与算法分析之---最短路径

本系列是阅读《数据结构与算法应用实践教程》第2版 主编 李文书 北京大学出版社 的读书笔记&#xff0c;加上自己的理解&#xff0c;更多的是学习的记录与反思&#xff0c;如有不妥&#xff0c;欢迎指正&#xff0c;非常感谢。转载于:https://www.cnblogs.com/guochaoxxl/p/712…

Quartz 2 Scheduler示例

Quartz是一个开源作业调度框架。 它可用于管理和计划应用程序中的作业。 步骤1&#xff1a;建立已完成的专案 创建一个Maven项目&#xff0c;如下所示。 &#xff08;可以使用Maven或IDE插件来创建它&#xff09;。 步骤2&#xff1a;图书馆 Quartz依赖项已添加到Maven的po…

sql server 2008 com.microsoft.sqlserver.jdbc.SQLServerException: 通过端口 1433 连接到主机

原内容搬迁到了新网站&#xff0c;给你带来的不便&#xff0c;敬请谅解&#xff01; 》 http://www.suanliutudousi.com/2017/08/28/sql-server-2008-com-microsoft-sqlserver-jdbc-sqlserverexception-%E9%80%9A%E8%BF%87%E7%AB%AF%E5%8F%A3-1433-%E8%BF%9E%E6%8E%A5%E5%88%B0…

如何通过网线连接两台电脑快速传输数据?

介绍 我们经常需要拷贝文件会用到类似U盘等工具&#xff0c;但我们有时在传输大文件时又苦于没有&#xff0c;那么大内存的转存工具。这时候我们就可以通过一条小小的网线连接两台电脑&#xff0c;形成一个小的局域网传输数据&#xff0c;因为是通过网线传输&#xff0c;所以传…

30分钟内使用MongoDB

最近&#xff0c;我被NoSQL错误咬住了-或是我的同事Mark Atwell提出的“燃烧在哪里&#xff01;” 运动。 尽管我无意于在不久的将来或可预见的将来回避友好的“ SELECT ... WHERE”&#xff0c;但我确实设法弄懂了一些代码。 在本文中&#xff0c;我分享了我在NoSQL世界中首次…

【Django】--ModelForm组件

ModelForm a.class Meta:model,#对应Model的  fieldsNone,#字段  excludeNone,#排除字段  labelsNone,#提示信息  help_texts None,#帮助提示信息  widgets None,#自定义插件  error_messages None,#自定义错误信息(整体错误信息from django.core.exceptions im…

mysql实际综合案例_Mysql综合案例

Mysql综合案例考核要点&#xff1a;创建数据表、单表查询、多表查询已知&#xff0c;有一个学生表student和一个分数表score&#xff0c;请按要求对这两个表进行操作。student表和score分数表的表结构分别如表1-1和表1-2所示。表1-1student表结构字段名数据类型主键外键非空唯一…

2012年I / O之后

从注册到赠品&#xff0c;每年的I / O疯狂都在不断发展。 在今年20分钟内被出售&#xff0c;并没有阻止Google赠送更多的东西。 以这种速度并有望在明年发布Google Glass&#xff0c;明年注册很可能会变得更加混乱&#xff01; 因此&#xff0c;Google&#xff0c;请停止提供免…

h5启动原生APP总结

许久没有写博客了&#xff0c;最近有个H5启动APP原生页面的需求&#xff0c;中间遇上一些坑&#xff0c;看了些网上的实现方案&#xff0c;特意来总结下 一、需要判断客户端的平台以及是否在微信浏览器中访问 1、客户端判断 在启动APP时&#xff0c;Android和IOS系统处理的方式…

mysql导入创建表空间_oracle创建表空间 用户 数据库导入和导出(转)

已经安装orcale 9i 和pl/sql(6.0)OracleJobSchedulerORCL、OracleOraDb10g_home1iSQL*PlusOracleOraDb10g_home1TNSListenerOracleServiceORCL第一个是oem控制台服务进程第二个是定时器和isql*plus的服务进程第三个是监听器的服务进程最后是数据库服务进程1. pl/sql客户机安装后…

什么时候使用Apache Camel?

Apache Camel是JVM / Java环境中我最喜欢的开源框架之一。 它可以轻松集成使用多种协议和技术的不同应用程序。 本文介绍了何时使用Apache Camel以及何时使用其他替代方法。 问题&#xff1a;企业应用程序集成&#xff08;EAI&#xff09; 由于新产品和新应用&#xff0c;几乎…

念整数

念整数&#xff08;5分&#xff09;题目内容&#xff1a; 你的程序要读入一个整数&#xff0c;范围是[-100000,100000]。然后&#xff0c;用汉语拼音将这个整数的每一位输出出来。 如输入1234&#xff0c;则输出&#xff1a; yi er san si注意&#xff0c;每个字的拼音之间有一…

python 比较运算符放在列表中_在Python3中将运算符放在列表中

我想把操作符作为一个列表&#xff0c;然后从列表中调用一个元素作为操作符。在如果我没有在运算符周围加引号&#xff0c;那么列表中逗号的语法错误&#xff1a;File "p22.py", line 24cat [,-,*]^SyntaxError: invalid syntax如果我把引语放在周围&#xff0c;那么…

软工个人总结

目录 一、个人提升二、写下属于自己的人月神话三、对下一届、后来人、自己的建议四、我的团队——Clover五、关于代码质量六、学过软件工程&#xff1f;七、自我介绍八、个性发挥一、个人提升 1. 开学初的目标 希望通过团队合作领会团队合作的内在精神&#xff0c;希望在分工完…