Java线程并发中常见的锁
随着互联网的蓬勃发展,越来越多的互联网企业面临着用户量膨胀而带来的并发安全问题。本文着重介绍了在java并发中常见的几种锁机制。
1.偏向锁
偏向锁是JDK1.6提出来的一种锁优化的机制。其核心的思想是,如果程序没有竞争,则取消之前已经取得锁的线程同步操作。也就是说,若某一锁被线程获取后,便进入偏向模式,当线程再次请求这个锁时,就无需再进行相关的同步操作了,从而节约了操作时间,如果在此之间有其他的线程进行了锁请求,则锁退出偏向模式。在JVM中使用-XX:+UseBiasedLocking
package jvmProject; import java.util.List;
import java.util.Vector; public class Biased { public static List<Integer> numberList = new Vector<Integer>();
public static void main(String[] args) {
long begin = System.currentTimeMillis();
int count = 0;
int startnum = 0;
while(count<10000000){
numberList.add(startnum);
startnum+=2;
count++;
}
long end = System.currentTimeMillis();
System.out.println(end-begin);
}
}
初始化一个Vector,往里面添加10000000个Integer对象,然后输出时间差。以此来测试偏向锁的性能。至于为什么要使用Vector而不使用ArrayList呢?
因为ArrayList是线程不安全的,Vector是线程安全的。这样说可能还不够具体,可以翻看一下源码吧。


Vector中的几乎所有操作是带有sychronized的,而ArrayList是没有的,所以Vector是线程安全的。
接下来我们来测试一下,开启偏向锁和不开启偏向锁对程序性能的影响有多大。
配置JVM启动(开启偏向锁)参数为:


配置JVM启动(关闭偏向锁)参数为:


Perfect!开启偏向锁的程序运行时间明显较短,开启偏向锁比不开启偏向锁,在单个线程中操作一个对象的同步方法,是有一定的优势的。其实也可以这样理解,当只有一个线程操作带有同步方法的Vector对象的时候,此时对Vector的操作就转变成了对ArrayList的操作。
偏向锁在锁竞争激烈的场合没有太强的优化效果,因为大量的竞争会导致持有锁的线程不停地切换,锁也很难保持在偏向模式,此时,使用偏向锁不仅得不到性能的优化,反而有可能降低系统的性能,因此,在激烈竞争的场合,可以尝试使用
-XX:-UseBiastedLocking参数禁用偏向锁。
2.轻量级锁
如果偏向锁失败,Java虚拟机就会让线程申请轻量级锁,轻量级锁在虚拟机内部,使用一个成为BasicObjectLock的对象实现的,这个对象内部由一个BasicLock对象和一个持有该锁的Java对象指针组成。BasicObjectLock对象放置在Java栈帧中。在BasicLock对象内部还维护着displaced_header字段,用于备份对象头部的Mark Word.
当一个线程持有一个对象的锁的时候,对象头部Mark Word信息如下
[ptr |00] locked
末尾的两位比特为00,整个Mark Word为指向BasicLock对象的指针。由于BasicObjectLock对象在线程栈中,因此该指针必然指向持有该锁的线程栈空间。当需要判断一个线程是否持有该对象时,只需要简单地判断对象头的指针是否在当前线程的栈地址范围即可。同时,BasicLock对象的displaced_header,备份了原对象的Mark word内容,BasicObjectLock对象的obj字段则指向持有锁的对象头部。
3.重量级锁
当轻量级锁失败,虚拟机就会使用重量级锁。在使用重量级锁的时,对象的Mark Word如下:
[ptr |10] monitor
重量级锁在操作过程中,线程可能会被操作系统层面挂起,如果是这样,线程间的切换和调用成本就会大大提高。
4.自旋锁
自旋锁可以使线程在没有取得锁的时候,不被挂起,而转去执行一个空循环,(即所谓的自旋,就是自己执行空循环),若在若干个空循环后,线程如果可以获得锁,则继续执行。若线程依然不能获得锁,才会被挂起。
使用自旋锁后,线程被挂起的几率相对减少,线程执行的连贯性相对加强。因此,对于那些锁竞争不是很激烈,锁占用时间很短的并发线程,具有一定的积极意义,但对于锁竞争激烈,单线程锁占用很长时间的并发程序,自旋锁在自旋等待后,往往毅然无法获得对应的锁,不仅仅白白浪费了CPU时间,最终还是免不了被挂起的操作 ,反而浪费了系统的资源。
在JDK1.6中,Java虚拟机提供-XX:+UseSpinning参数来开启自旋锁,使用-XX:PreBlockSpin参数来设置自旋锁等待的次数。
在JDK1.7开始,自旋锁的参数被取消,虚拟机不再支持由用户配置自旋锁,自旋锁总是会执行,自旋锁次数也由虚拟机自动调整。
Java线程并发中常见的锁的更多相关文章
- Java线程并发中常见的锁--自旋锁 偏向锁
随着互联网的蓬勃发展,越来越多的互联网企业面临着用户量膨胀而带来的并发安全问题.本文着重介绍了在java并发中常见的几种锁机制. 1.偏向锁 偏向锁是JDK1.6提出来的一种锁优化的机制.其核心的思想 ...
- Java线程并发:知识点
Java线程并发:知识点 发布:一个对象是使它能够被当前范围之外的代码所引用: 常见形式:将对象的的引用存储到公共静态域:非私有方法中返回引用:发布内部类实例,包含引用. 逃逸:在对象尚未准备 ...
- (转载)java高并发:CAS无锁原理及广泛应用
java高并发:CAS无锁原理及广泛应用 版权声明:本文为博主原创文章,未经博主允许不得转载,转载请注明出处. 博主博客地址是 http://blog.csdn.net/liubenlong007 ...
- Java 线程池中的线程复用是如何实现的?
前几天,技术群里有个群友问了一个关于线程池的问题,内容如图所示: 关于线程池相关知识可以先看下这篇:为什么阿里巴巴Java开发手册中强制要求线程池不允许使用Executors创建? 那么就来和大家探讨 ...
- 使用Java线程并发库实现两个线程交替打印的线程题
背景:是这样的今天在地铁上浏览了以下网页,看到网上一朋友问了一个多线程的问题.晚上闲着没事就决定把它实现出来. 题目: 1.开启两个线程,一个线程打印A-Z,两一个线程打印1-52的数据. 2.实现交 ...
- Java高并发的常见应对方案
Java高并发的常见应对方案 一.关于并发我们说的高并发是什么? 在互联网时代,高并发,通常是指,在某个时间点,有很多个访问同时到来. 高并发,通常关心的系统指标与业务指标? QPS:每秒钟查询量,广 ...
- Java线程池中的核心线程是如何被重复利用的?
真的!讲得太清楚了!https://blog.csdn.net/MingHuang2017/article/details/79571529 真的是解惑了 本文所说的"核心线程". ...
- Java中常见的锁分类以及对应特点
对于 Java 锁的分类没有严格意义的规则,我们常说的分类一般都是依据锁的特性.锁的设计.锁的状态等进行归纳整理的,所以常见的分类如下: 公平锁和非公平锁:公平锁是多线程按照锁申请的顺序获取锁,非公平 ...
- java并发系列 - 第29天:高并发中常见的限流方式
这是java高并发系列第29篇. 环境:jdk1.8. 本文内容 介绍常见的限流算法 通过控制最大并发数来进行限流 通过漏桶算法来进行限流 通过令牌桶算法来进行限流 限流工具类RateLimiter ...
随机推荐
- 微软再次要求Google审查官方链接 称将进行调查
之前代表微软向Google发出DMCA删除通知的反盗版公司再次要求Google审查Microsoft.com官网链接.微软对此表示将进行调查,已经要求反盗版公司停止以微软的名义发出DMCA通知. 仅仅 ...
- 谁能完全搞懂Visual Studio的安装项?
大家都知道,Visual Studio绝对不是“一个程序”那么简单,不管哪个版本,安装好之后总会在“删除程序”中生成一大堆你或懂或不懂的东西.但很少人关注过究竟包括哪些东西.我最近装了一次Visual ...
- [FPGA] 2、新建并运行一个工程
上一篇将开发板的情况大致介绍了一下,这次将一步一步展示如何新建.调试并下载运行一个点亮LED的工程. 1)打开Quartus新建工程: 2)填写规则大致如下: 3)选择我们芯片的类型: 4)点击fil ...
- CocoaPod问题
CocoaPod问题 升级10.11后使用CocoaPod出现-bash: pod: command not found 解决办法 字数91 阅读10946 评论24 喜欢27 升级10.11后,运行 ...
- [_CN] Eclipse精要与高级开发技术 note
一 eclipse是基于java的 ide ,但根据其体系结构,开发插件,也可拓展到其他语言———————— 尽管如此,但还是很少听说用eclipse来写php或者c的 跨os 三个项目:eclips ...
- jQuery的extend方法的深层拷贝
一些东西长时间不用就忘了,比如这个jQuery的extend方法的深层拷贝,今天看单页应用的书的时候,看到entend第一个参数是true,都蒙了.也是,自己的大部分对jQuery的学习知识来自锋利的 ...
- PSR规范
背景 Framework Interoperability Group(框架可互用性小组),简称 FIG,成立于 2009 年.FIG 最初由几位知名 PHP 框架开发者发起,在吸纳了许多优秀的大脑和 ...
- 无服务端纯前台导出数据到Excel-JSExcelXML.js 使用指南
JSExcelXML 使用指南 先来个效果预览 a.前端显示 b.导出excel效果 表头部分 表尾部分 1.功能描述 JsExcelXml 采用js生成excel中可显示的xml格式文本,将输出文本 ...
- Android WebView 开发教程
声明在先:必须在AndroidMainfest.xml 里面声明权限,否则在Java里面编写的所有WebView浏览网页的代码都无法正常使用 <uses-permission android:n ...
- 创建oracle数据库job服务:PlSqlDev操作job
PlSqlDev操作job 创建job 1.选择job文件夹,右键 2.点击新建 3.对应填写完成,可以点击“查看SQL”查看sql语句,确定无误后,点击“应用”即创建完成 4.此时, ...