
课程咨询: 400-996-5531 / 投诉建议: 400-111-8989
认真做教育 专心促就业
锁的应用与优化在许多Java编程开发项目中都是非常常见的一个编程开发技术应用,而本文我们就通过案例分析来简单了解一下,锁的应用与优化都有哪些方法。
1、自旋锁
互斥同步由于线程的挂起和回复线程的操作都需要从用户态和内核态的切换,导致jvm并发性能的降低。但是共享数据的锁定状态有时候只会持续一小段时间,为了加锁去挂起和恢复线程并不值得。自旋锁应运而生,不让线程立马挂起而是让线程执行自旋让线程等待锁的释放。
2、锁粗化
随让我们通常推荐锁的粒度尽可能小,从而提高性能,但是如果对一个对象重复的进行加锁解锁,甚至是在for循环中加锁解锁,那么即使没有线程竞争,频繁进行互斥同步也是非常浪费性能,也许虚拟机会帮我们扩大锁的范围,比如扩大到for循环的外部,这样只需要进行一次加锁解锁了
3、偏向锁
hotspot的作者经过研究发现,大多数情况下,锁不仅不存在多线程竞争,还常常是由同一个线程多次获取,那么能不能让锁记录这个线程,下次这个线程来直接获取锁即可,从而降低获得锁的代价。当一个线程范围同步块并且获取锁时,会在对象头和站在栈帧中记录存储锁偏向的线程ID,以后进入和退出同步块的时候都不需要进行CAS操作加锁和解锁。
4、偏向锁的获取
直接看对象头中是否存储了当前线程的id,如果存储了那么当前线程拿到锁,这就是偏向的含义,如果失败,那么再看下当前锁标志位是否是01,01表示无锁或者偏向锁,继续判断是否是偏向锁,如果是偏向锁那么需要查看是否存储了当前线程id,如果没有存储任何线程id那就CAS设置线程id。如果当前时无锁也是CAS设置线程Id
5、轻量级锁
线程在执行同步块之前,JVM会先在当前线程的栈帧中创建用于存储锁记录的空间(lockrecord)并且将对象头中的markword赋值到锁记录lockrecord中,这种操作叫做Displacedmarkword。然后线程产品使用CAS把对象头的markword替换为指向锁记录的指针,如果成功那么表示当前线程获取到锁,如果失败,表示存在其他线程竞争锁,当前线程将通过自旋的方式获取锁。轻量级锁解决了竞争线程不多,并且锁很快就释放,这时候挂起唤醒线程不划算,通过自旋减少用户态到内核态的切换。
【免责声明】本文系本网编辑部分转载,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及作品内容、版权和其它问题,请在30日内与管理员联系,我们会予以更改或删除相关文章,以保证您的权益!更多内容请加danei0707学习了解。欢迎关注“达内在线”参与分销,赚更多好礼。