Java多线程之锁优化策略
转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6561264.html
锁的优化策略
编码过程中可采取的锁优化的思路有以下几种:
1:减少锁持有时间
例如:对一个方法加锁,不如对方法中需要同步的几行代码加锁;
2:减小锁粒度
例如:ConcurrentHashMap采取对segment加锁而不是整个map加锁,提高并发性;
3:锁分离
根据同步操作的性质,把锁划分为的读锁和写锁,读锁之间不互斥,提高了并发性。
4:锁粗化
这看起来与思路1有冲突,其实不然。思路1是针对一个线程中只有个别地方需要同步,所以把锁加在同步的语句上而不是更大的范围,减少线程持有锁的时间;
而锁粗化是指:在一个间隔性地需要执行同步语句的线程中,如果在不连续的同步块间频繁加锁解锁是很耗性能的,因此把加锁范围扩大,把这些不连续的同步语句进行一次性加锁解锁。虽然线程持有锁的时间增加了,但是总体来说是优化了的。
5:锁消除
锁消除是编译器做的事:根据代码逃逸技术,如果判断到一段代码中,堆上的数据不会逃逸出当前线程(即不会影响线程空间外的数据),那么可以认为这段代码是线程安全的,不必要加锁。
Java虚拟机中采取的锁优化策略:
1:偏向锁:锁对象偏向于当前获得它的线程,如果在接下来的没有被其他线程请求,则持有该锁的线程将不再需要进行同步操作(即:持有该锁的线程在接下来的执行中遇到同步块时不再需要lock和unlock了,直接执行即可)。当另一个线程申请该锁时,当前线程的偏向模式才会结束,让出该锁。
2:轻量级锁:syncrhoized的底层实现是通过监视器monitor来控制的,而monitorenter与monitorexit这两个原语是依赖操作系统互斥(mutex)来实现的。
互斥会导致线程挂起,并在较短的时间内又需要重新调度回原线程的,较为消耗资源。轻量级锁(Lightweight Locking)利用了CPU原语Compare-And-Swap(CAS,汇编指令CMPXCHG),尝试在进入互斥前,进行补救,减少多线程进入互斥的几率。
如果偏向锁失败,那么系统会进行轻量级锁的操作,使用CAS操作来尝试加锁。如果轻量级锁失败,才调用系统级别的重量级锁(syncrhoized)来加锁。
3:自旋锁:当线程申请锁时,锁被占用,则让当前线程执行一个忙循环(自旋),看看持有锁的线程是否会很快释放锁。如果自旋后还没获得锁,才进入同步阻塞状态;
3.1:自适应自旋:自旋的线程自旋的时间为同一个锁上一次线程自旋并获得锁的耗时。如果对于这个锁,自旋很少有成功的,就不自旋了,避免浪费CPU资源。
为了尽量避免使用重量级锁(操作系统层面的互斥),JVM首先会尝试轻量级锁,轻量级锁会尝试使用CAS操作来获得锁,如果轻量级锁获得失败,说明存在竞争。但是也许很快就能获得锁,就会尝试自旋锁,将线程做几个空循环,每次循环时都不断尝试获得锁。如果自旋锁也失败,那么只能升级成重量级锁。
Java多线程之锁优化策略的更多相关文章
- java多线程编程——锁优化
并发环境下进行编程时,需要使用锁机制来同步多线程间的操作,保证共享资源的互斥访问.加锁会带来性能上的损坏,似乎是众所周知的事情.然而,加锁本身不会带来多少的性能消耗,性能主要是在线程的获取锁的过程.如 ...
- Java多线程编程 — 锁优化
阅读目录 一.尽量不要锁住方法 二.缩小同步代码块,只锁数据 三.锁中尽量不要再包含锁 四.将锁私有化,在内部管理锁 五.进行适当的锁分解 正文 并发环境下进行编程时,需要使用锁机制来同步多线程间 ...
- Java多线程编程—锁优化
并发环境下进行编程时,需要使用锁机制来同步多线程间的操作,保证共享资源的互斥访问.加锁会带来性能上的损坏,似乎是众所周知的事情.然而,加锁本身不会带来多少的性能消耗,性能主要是在线程的获取锁的过程.如 ...
- JAVA多线程与锁机制
JAVA多线程与锁机制 1 关于Synchronized和lock synchronized是Java的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码 ...
- Java 多线程:锁(二)
Java 多线程:锁(二) 作者:Grey 原文地址: 博客园:Java 多线程:锁(二) CSDN:Java 多线程:锁(二) AtomicLong VS LongAddr VS Synchroni ...
- Java 虚拟机对锁优化所做的努力
作为一款公用平台,JDK 本身也为并发程序的性能绞尽脑汁,在 JDK 内部也想尽一切办法提供并发时的系统吞吐量.这里,我将向大家简单介绍几种 JDK 内部的 "锁" 优化策略. 1 ...
- Java 多线程:锁(一)
Java 多线程:锁(一) 作者:Grey 原文地址: 博客园:Java 多线程:锁(一) CSDN:Java 多线程:锁(一) CAS 比较与交换的意思 举个例子,内存有个值是 3,如果用 Java ...
- Java 多线程:锁(三)
Java 多线程:锁(三) 作者:Grey 原文地址: 博客园:Java 多线程:锁(三) CSDN:Java 多线程:锁(三) StampedLock StampedLock其实是对读写锁的一种改进 ...
- 深入理解多线程(五)—— Java虚拟机的锁优化技术
本文是<深入理解多线程>的第五篇文章,前面几篇文章中我们从synchronized的实现原理开始,一直介绍到了Monitor的实现原理. 前情提要 通过前面几篇文章,我们已经知道: 1.同 ...
随机推荐
- window.opener()方法
<!DOCTYPE html><html><head><meta charset="GBK"><title>菜鸟教程(r ...
- TeXworks使用教程指南
TeXworks是Windows版本的TeX Live默认提供的编辑器.值得注意的是,TeXworks 是XeTeX 作者 Jonathan Kew 开发的,其特点是界面简洁友好,集成了轻便的 PDF ...
- endnote插入参考文献后的对齐方式和缩进空格
原文链接 https://jingyan.baidu.com/article/63acb44a3f0f6161fcc17ed0.html 1 2 3 4 5 6 7 分步阅读 1.endnote 导入 ...
- [转]PHP: 深入pack/unpack
From : http://my.oschina.net/goal/blog/195749 http://www.w3school.com.cn/php/func_misc_pack.asp PHP作 ...
- MSDN离线版 发现不少人都在找这个
MSDN离线版 发现不少人都在找这个,无意中找到 VS2012旗舰版 选好语言,建议选那个ISO的下载
- [leetcode]Multiply Strings @ Python
原题地址:https://oj.leetcode.com/problems/multiply-strings/ 题意: Given two numbers represented as strings ...
- Visio中方向键不能移动物件而是滚动画布
不知怎么的, 我的Visio中按方向键不能移动目标对象, 效果却是移动整个画布. 上网查了一下, 找到了原因. 因为不知怎么的错按了键盘上的Scroll Lock键, 再按一下就好了. 参考资 ...
- 领扣-5 最长回文子串 Longest Palindromic Substring MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- javascript运算符instanceof
概述 instanceof 运算符可以用来判断某个构造函数的prototype属性是否存在另外一个要检测对象的原型链上. 语法 object instanceof constructor 参数 obj ...
- VB.NET,C#.NET调用Web Service,利用visual studio 的实现方法
下面是一篇文章比较详细,其实具体操作很简单,把Web Service服务地址,利用工具(VS2010),通过添加引用的形式,添加到项目中来就可以应用了. 大家如果这个地方不会操场的话,可以问问我QQ: ...