java锁实现_Java锁实现

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博客。

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

java锁实现

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

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

相关文章

2023年12月青少年机器人技术等级考试(五级) 实操试卷

主题&#xff1a;按键控制心形图案交互显示 器件&#xff1a;ESP32主控板1块&#xff0c;按键模块1个&#xff0c;8x8LED点阵1个&#xff0c;74HC595移位寄存器芯片&#xff08;或模块&#xff09;及相应辅件。以上模块也可使用分立器件结合面包板搭建。 任务要求&#xff1a; …

MATLAB正太分布函数

normcdf(x); %标准正态分布的分布函数。 normcdf(x,mu,sigma); %带平均值和方差μ和σ的正态分布&#xff0c;标准正态分布就是mu0,sigma1的特例。%例如>> normcdf(0,0,1)ans 0.5>> normcdf(inf,0,1)ans 1>> normcdf(-inf,0,1)ans 0

编写自己的工具箱 (一)

仔细想了一下 决定先解决一下调用的问题&#xff0c; 这样无比要解决异步获取 !function(){var requireOption window.requireOption || {path : ,};var windowIsLoad false;var key setInterval(function(){if( document.body || windowIsLoad ){windowIsLoad true;clearI…

ANTLR入门:构建一种简单的表达语言

这是该系列的第一篇文章。 本系列的目的是描述如何创建有用的语言和所有支持工具。 在本文中&#xff0c;我们将开始研究一种非常简单的表达语言。 我们将在语言沙箱中构建它&#xff0c;因此我们将其称为语言Sandy 。 我认为工具支持对于一种语言至关重要&#xff1a;因此&a…

Matlab回归分析regress和polyfit

在matlab中regress()函数和polyfit()函数都可以进行回归分析。 (1)regress()函数主要用于线性回归,一元以及多元的。它可以提供更多的信息,残差之类的。 (2)polyfit()函数是利用多项式拟合。可以是线性也可以是非线性的。 (1)regress()函数详解 [b,bint,r,…

ACM计算几何题目推荐

一。基础题目 1.1 有固定算法的题目 A&#xff0c; 最近点对问题 最近点对问题的算法基于扫描线算法。 ZOJ 2107 Quoit Design 典型最近点对问题 POJ 3714 Raid 变种最近点对问题 B&#xff0c;最小包围圆 最小包围圆的算法是一种增量算法&#xff0c;期望…

洛谷 P1027 Car的旅行路线

P1027 Car的旅行路线 题目描述 又到暑假了&#xff0c;住在城市 AA 的 CarCar 想和朋友一起去城市 BB 旅游。她知道每个城市都有 44 个飞机场&#xff0c;分别位于一个矩形的 44 个顶点上&#xff0c;同一个城市中 22 个机场之间有 11 条笔直的高速铁路&#xff0c;第 II 个城市…

Matlab各种拟合

线性拟合见上一篇《回归分析》 非线性拟合: cftool %curve fitting toolbox非线性函数拟合工具箱。要确定系数的初始值和上下限(sftool用于三维的) %该函数可以生成m文件函数,方便在编程中使用,但是生成的m文件函数拟合的结果会有很大的误差和图形界面的结果不一样 1 comman…

Matlab线性规划(Linear Programming)

bintprog&#xff1a;0-1规划linprog:线性规划quadprogoptimtool整数规划第三方工具箱&#xff1a;YALMIP http://users.isy.liu.se/johanl/yalmip/pmwiki.php?nMain.Download

java(IO)读写文件乱码转换UTF-8问题

java(IO)读写文件乱码转换UTF-8问题 读取文件String Content  ""; // 文件很长的话建议使用StringBuffertry {FileInputStream fsnew FileInputStream("文件录取");InputStreamReader isr  new InputStreamReader(fis, "UTF-8");Buff…

类固醇上的Java:5种超级有用的JIT优化技术

Java开发人员&#xff1f; 优化您的生产监控。 请在所有已记录的错误&#xff0c;警告和异常之后查看源代码&#xff0c;调用堆栈和变量状态- 尝试Takipi 。 最有用的JVM JIT优化有哪些&#xff1f;如何使用它们&#xff1f; 即使您没有积极计划&#xff0c;JVM也有很多技巧可…

poj3714 最近点对

最近点对&#xff0c;采用分治方法。过程&#xff1a; 1对原数组依据x左标从小到大排序。 2二分数组&#xff0c;左边求出最小值&#xff0c;右边求出最小值&#xff0c;我们求最小的。 3找出对于左右两边的可能小于当前最小值的最近点对&#xff0c;更新最小值。 这题目需要区…

Matlab 格式化字符串sscanf

sscanf 是按一定的格式从字符串中读取出字符,它有以下几种用法: A = sscanf(str, format) A = sscanf(str, format, sizeA) [A, count] = sscanf(...) [A, count, errmsg] = sscanf(...) [A, count, errmsg, nextindex] = sscanf(...) Description A = sscanf(str, forma…

2018牛客暑假多校二 D(贪心)

题目描述&#xff1a; 你要按照顺序以此经过n个商店&#xff0c;每到达一个商店你可以购买一件物品&#xff0c;也可以出售你手中的商品。 同一时刻你手上最多拿一件商品。在第i个商店购买和出售的代价都是a[i]。 问你经过完n个商店后的最大收益。 同时&#xff0c;在最大化收…

ZOJ1450 Minimal Circle 最小圆覆盖

包含点集所有点的最小圆的算法 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId450 平面上有n个点&#xff0c;给定n个点的坐标&#xff0c;试找一个半径最小的圆&#xff0c;将n 个点全部包围&#xff0c;点可以在圆上。 1. 在点集中任取3点A,B,C。 2. 作一个包…

遗传算法各Matlab工具箱简介

关于matlab遗传算法工具箱主要有三种&#xff1a;1、gaot工具箱&#xff1a;这是网上流传的免费的工具箱&#xff0c;网上对它介绍的资料也挺多&#xff0c;它不是Matlab软件自带的&#xff0c;但可以自己配置使用。飞思科技产品研发中心编著《Matlab 6.X辅助优化计算与设计》第…

独眼巨人反应组织了Java 8库的寒武纪爆发

什么是独眼巨人反应&#xff1f; Lambda表达式和默认方法在Java 8中的出现预示了Java语言十年来最大的结构性变化。 在此基础上构建了一些新的很酷的API&#xff0c;例如Stream, Optional, CompletableFuture最终Java开发人员可以以更实用的样式进行编码。 尽管这是非常受欢迎的…

C语言中文件定位函数总结

C语言中文件定位函数主要是&#xff1a;fseek, ftell, fsetpos, fgetpos。 先来讲前两个函数&#xff0c;这是最基本的定位函数&#xff1a; fseek函数&#xff1a;能把文件指针移动到文件任何位置&#xff0c;其原型是&#xff1a;int fseek(FILE *fp, long offset, int fromw…

API

api 百科名片 API&#xff08;Application Programming Interface,应用程序编程接口&#xff09;是一些预先定义的函数&#xff0c;目的是提供应用程序与开发人员基于某软件或硬件的以访问一组例程的能力&#xff0c;而又无需访问源码&#xff0c;或理解内部工作机制的细节。目…

Matlab gatool使用方法

可以通过输入gatool或者optimtool(ga)打开图形界面或者用ga()运行命令行函数设置Fitnessfunction 和对应的Number of variables,为了提高效率最好向量化适应度函数,然后设置Vectorize参数为On可以选择相应参数进行设置Population种群参数Fitness scalling适应度比例参数Selecti…