为什么80%的码农都做不了架构师?>>>   

在介绍锁之前我们先介绍一个线程不安全的例子,一个全局的list,开2个线程往里面插入数据,代码如下:

package com.jvm.day6.lock.demo;import java.util.ArrayList;
import java.util.List;/*** 测试都线程共享一个变量带来的现象* @Author:xuehan* @Date:2016年3月20日下午3:35:29*/
class NumberAdd implements Runnable{public static  List<Integer> numberList =new ArrayList<Integer>();public static int startNum;public NumberAdd(int startNum){this.startNum = startNum;}@Overridepublic void run() {int count = 0;while(count < 1000000){numberList.add(count ++ );startNum = startNum + 2;}}
}
public class Test{public static void main(String[] args) throws Exception {Thread t1 = new Thread(new NumberAdd(1));Thread t2 = new Thread(new NumberAdd(0));t1.start();t2.start();while(t1.isAlive() || t2.isAlive()){Thread.sleep(2);}System.out.println("集合大小" + NumberAdd.numberList.size() );System.out.println( "最后一个值的大"  + NumberAdd.numberList.get(NumberAdd.numberList.size() - 1));for(int i = NumberAdd.numberList.size()  - 10 ;  i < NumberAdd.numberList.size() -1; i ++){System.out.println(NumberAdd.numberList.get(i));}}
}


 按照开始想的,集合里面应该有200万个数据了,结果却出现了数组越界的错误,为什么呢,这是因为ArrayList不是线程安全的,用来存放数据的elementData是共享的, 线程A往list里添加数据的时候刚验证大小通过,还没有插入,然后轮到线程B执行,线程B刚好插入了list该扩容的最后一个元素,然后list满了,线程A执行,A线程往集合里面插入元素,引起了数据越界。


 

jvm锁

每个对象都一个mark头,他的作用是:

Mark Word,对象头的标记,32位

描述对象的hash、锁信息,垃圾回收标记,年龄

指向锁记录的指针

指向monitor的指针

GC标记

偏向锁线程ID

偏向锁
jvm控制,可以设置jvm启动参数
大部分情况是没有竞争的,所以可以通过偏向来提高性能
所谓的偏向,就是偏心,即锁会偏向于当前已经占有锁的线程
将对象头Mark的标记设置为偏向,并将线程ID写入对象头Mark
只要没有竞争,获得偏向锁的线程,在将来进入同步块,不需要做同步
当其他线程请求相同的锁时,偏向模式结束
-XX:+UseBiasedLocking -jdk6需要手动打开
默认启用
在竞争激烈的场合,偏向锁会增加系统负担
偏向锁是系统自带的设置参数开启,java代码如下:
package com.jvm.day6.lock;import java.util.List;
import java.util.Vector;/***使用 偏向锁-XX:+UseBiasedLocking -XX:BiasedLockingStartupDelay=0* 不使用偏向锁-XX:-UseBiasedLocking* 根据测试下面代码使用偏向锁可提高150毫秒执行时间 150/2300,提高效率6% * @Author:xuehan* @Date:2016年3月19日下午12:06:15*/
public class DeflectionLock {public static List<Integer> numberList =new Vector<Integer>();public static void main(String[] args) throws InterruptedException {System.out.println((int)'l');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);}
}

根据我的写实偏向锁可以提高性能6%

轻量级锁  BasicObjectLock,这个锁是嵌入到线程栈中的,他有两部组成 BasicLock和 ptr to obj hold the lock, BasicLock里面存放着对象头, ptr to obj hold the lock为指向持有对象锁的指针
普通的锁处理性能不够理想,轻量级锁是一种快速的锁定方法。
如果对象没有被锁定
将对象头的Mark指针保存到锁对象中
将对象头设置为指向锁的指针(在线程栈空间中)

如果轻量级锁失败,表示存在竞争,升级为重量级锁(常规锁)

在没有锁竞争的前提下,减少传统锁使用OS互斥量产生的性能损耗

在竞争激烈时,轻量级锁会多做很多额外操作,导致性能下降

自旋锁
当竞争存在时,如果线程可以很快获得锁,那么可以不在OS层挂起线程,让线程做几个空操作(自旋)
JDK1.6中-XX:+UseSpinning开启
JDK1.7中,去掉此参数,改为内置实现
如果同步块很长,自旋失败,会降低系统性能
如果同步块很短,自旋成功,节省线程挂起切换时间,提升系统性能

上面的一些锁不是Java语言层面的锁优化方法

他们是内置于JVM中的获取锁的优化方法和获取锁的步骤

偏向锁可用会先尝试偏向锁

轻量级锁可用会先尝试轻量级锁

以上都失败,尝试自旋锁

再失败,尝试普通锁,使用OS互斥量在操作系统层挂起

我们可以从以下方面对锁进行优化

减少锁的时间

没必须放在同步块的代码尽量不要放在代码块里

减少锁的粒度

将大对象,拆成小对象,大大增加并行度,降低锁竞争

偏向锁,轻量级锁成功率提高

实现的例子如ConcurrentHashMap

使用若干个Segment :Segment<K,V>[] segments

Segment中维护HashEntry<K,V>

put操作时

先定位到Segment,锁定一个Segment,执行put

在减小锁粒度后, ConcurrentHashMap允许若干个线程同时进入

锁分离

根据功能进行锁分离

ReadWriteLock

读多写少的情况,可以提高性能


 读写分离思想可以延伸,只要操作互不影响,锁就可以分离

LinkedBlockingQueue

队列

链表


 锁粗化

通常情况下,为了保证多线程间的有效并发,会要求每个线程持有锁的时间尽量短,即在使用完公共资源后,应该立即释放锁。只有这样,等待在这个锁上的其他线程才能尽早的获得资源执行任务。但是,凡事都有一个度,如果对同一个锁不停的进行请求、同步和释放,其本身也会消耗系统宝贵的资源,反而不利于性能的优化

for(int i=0;i<1000;i++){synchronized(lock){}}
// 应该写成
synchronized(lock){for(int i =0; i < 1000; i ++){}
}

这时候我们要增加锁的持有时间不要让请求和释放锁频繁的发生

锁消除

在java方法体里如果不是共享的变量不需要同步操作的,这时候jvm会自动的优化把锁去掉,如StingBuffer和Vector,使用锁消除

-server -XX:+DoEscapeAnalysis -XX:+EliminateLocks

关闭锁消除

-server -XX:+DoEscapeAnalysis -XX:-EliminateLocks

无锁

锁是悲观的操作

无锁是乐观的操作

无锁的一种实现方式

CAS(Compare And Swap),CAS是原子的

非阻塞的同步

CAS(V,E,N)

在应用层面判断多线程的干扰,如果有干扰,则通知线程重试,一般这样做会让程序变的复杂,但性能更加好。

转载于:https://my.oschina.net/zaxb/blog/1544121

jvm第7节-锁(偏向锁,轻量锁,自旋锁)相关推荐

  1. 并发系列三:证明分代年龄、无锁、偏向锁、轻量锁、重(chong)偏向、重(chong)轻量、重量锁

    前言 上篇文章咱们了解了synchronized关键字的常见用法.对象头以及证明了一个对象在无锁状态下的对象头markwork部分的前56位存储的是hashcode.接下来,咱们继续来根据对象头分别证 ...

  2. 自旋锁和互斥锁实例_多线程编程之自旋锁

    一.什么是自旋锁 一直以为自旋锁也是用于多线程互斥的一种锁,原来不是! 自旋锁是专为防止多处理器并发(实现保护共享资源)而引入的一种锁机制.自旋锁与互斥锁比较类似,它们都是为了解决对某项资源的互斥使用 ...

  3. Linux 锁机制(3)之自旋锁

    Linux 锁机制(3)之自旋锁 1. 自旋锁 1.1 两种锁 1.2 自旋锁 1.3 自旋名字来源:自旋锁一直循环等待,直到获取锁为止. 1.4 自旋锁优点: 2 自旋锁特点/使用: 2.1 临界区 ...

  4. 一文看懂临界区、互斥锁、同步锁、临界区、信号量、自旋锁等名词!

    点击上方"业余草",选择"置顶公众号" 第一时间获取技术干货和业界资讯! 关于线程安全的专有名词有一大堆.你们突然之间问我这个名词是什么意思,那个名词是什么意思 ...

  5. 自旋锁与互斥锁的对比、手工实现自旋锁

    自旋锁与互斥锁的对比.手工实现自旋锁 版权声明:本文为博主原创文章,转载请注明出处,谢谢. https://blog.csdn.net/FreeeLinux/article/details/53695 ...

  6. 2021面试 Lock,synch,dcl双检查锁sy+volite,悲观锁,偏向,轻量锁,重量锁,升级12

    0.数据库悲观锁:for update: MySQL实现悲观锁_九色鹿-CSDN博客_mysql悲观锁怎么实现 1. ReentrantLock锁公平与非公平实现.重入原理:  ReentrantLo ...

  7. 锁优化:逃逸分析、自旋锁、锁消除、锁粗化、轻量级锁和偏向锁

    1. 逃逸分析 Escape Analysis 1.1 逃逸分为两种: 方法逃逸:当一个对象在方法中被定义后,可能作为调用参数被外部方法说引用. 线程逃逸:通过复制给类变量或者作为实例变量在其他线程中 ...

  8. 轻量级锁的加锁和解锁逻辑-自旋锁

    轻量级锁在加锁过程中,用到了自旋锁 所谓自旋,就是指当有另外一个线程来竞争锁时,这个线程会在原地循环等待,而不是把该线程给阻塞,直到那个获得锁的线程释放锁之后,这个线程就可以马上获得锁的. 注意,锁在 ...

  9. 【面试 分布式锁详细解析】续命 自旋锁 看门狗 重入锁,加锁 续命 解锁 核心源码,lua脚本解析,具体代码和lua脚本如何实现

    Redisson实现分布式锁原理 自己实现锁续命 在 controller 里开一个 线程 (可以为 守护线程) 每10秒,判断一个 这个 UUID是否存在,如果 存在,重置为 30秒. 如果不存在, ...

  10. Juc07_乐观锁和悲观锁、公平锁和非公平锁、递归锁(可重入锁)、死锁及排查、自旋锁

    文章目录 ①. 乐观锁和悲观锁 ②. 公平锁和非公平锁 ③. 可重入锁(又名递归锁) ④. 死锁及排查 ⑥. 自旋锁 ①. 乐观锁和悲观锁 ①. 悲观锁(synchronized关键字和Lock的实现 ...

最新文章

  1. Python break语句,continue语句,pass 语句
  2. HDU-3068-最长回文 (Manacher算法)
  3. 如何解决问题:程序无法正常启动(0xc0000022)
  4. 【Microsoft Word】Aurora插入公式点击Refresh,提示Problems running LaTex解决方法
  5. 零基础学Java有哪些必看书?推荐这5本
  6. 深度学习之生成对抗网络(2)GAN原理
  7. JDBC 数据库连接操作——实习第三天
  8. 语句练习题 折纸、阶乘、阶乘求和、范围内条件查找(水仙花数)。
  9. 调用指定目录下的批处理bat_批处理(.bat)的奇技淫巧
  10. 以软件开发周期来说明不同的测试的使用情况
  11. Sturts2【四】 StrutsPrepareAndExecuteFilter源码分析二
  12. VMware Workstation pro无法在Windows上运行的解决方法
  13. lme4 | 在R中运行混合效应模型(多层模型)
  14. 阿里云视频点播 和HLS加密解密
  15. CentOS7关于hostname
  16. 普通二维码跳转微信小程序
  17. 关闭Postman v5.0自动更新
  18. java ibm notes_使用Java API从Lotus Notes NSF文件中提取电子邮件
  19. 特斯拉“深陷”召回/监管调查,“高田气囊门”是前车之鉴
  20. 测绘资质专业类别及乙级作业限制范围是什么?

热门文章

  1. 重磅!中国微纳机器人技术取得新突破,实现肿瘤的可视化精准治疗!
  2. 大脑与数学——利用代数拓扑研究模拟大脑 第一部分
  3. 观点|重磅出炉!29页《业内观点:机器人行业的未来》
  4. 用洪小文,人工智能予力永续未来
  5. 打开脑科学研究的另一扇窗:脑神经化学活体原位电化学分析新技术
  6. 从ACT-R探讨认知智能
  7. 量化人类社会交互行为
  8. 关于未来的10点核心思考
  9. GPU、FPGA芯片成为增强机器学习能力的“左膀右臂”
  10. 2018年中国人工智能行业研究报告|附下载