Java多线程——锁概念与锁优化
为了性能与使用的场景,Java实现锁的方式有非常多。而关于锁主要的实现包含synchronized关键字、AQS框架下的锁,其中的实现都离不开以下的策略。
悲观锁与乐观锁
- 乐观锁。乐观的想法,认为并发读多写少。每次操作的时候都不上锁,直到更新的时候才通过CAS判断更新。对于AQS框架下的锁,初始就是乐观锁,若CAS失败则转化为悲观锁。
- 悲观锁。悲观的想法,认为并发写多读少。每次操作数据都上锁,即使别人想读也要先获得锁才能读。对于1.6以前的synchronized关键字,则是悲观锁的实现之一。
CAS无锁算法
全称为 Compare and Swap。CAS有三个操作数,内存值V,旧预期值(已获得的旧数据)A,修改新值B。当且仅当V与A的值相同(compare),才能把V替换为B(Swap)。其中Java中内存值可以通过volatile关键字标识获取,该关键词可以使变量对所有线程实时可见。
CAS算法在锁的应用非常广泛,java中concurrent包的高性能都是基于这个算法,可以说没有CAS,并发包的高性能也就不存在了。
重量级锁
悲观锁的一种。互斥使代码执行可以同步,但这种方式成本比较高,涉及到操作系统的调用阻塞,会造成一些系统资源的浪费。1.6以前,在Java中的即是监视器锁,把.java文件编程成.class文件后能看到synchronized关键字就是通过monitorenter和monitorexit这个两个字节码指令来实现的。
轻量级锁
由于在没有很多线程竞争的前提下,重量级锁会导致性能资源的浪费。每次判断是否无锁,无锁则建锁记录,有锁通过CAS去尝试获取锁(对比Mark Word)。该过程失败会让锁膨胀为重量级锁。
偏向锁
是轻量级锁的优化,适用于无多线程竞争。虽然轻量级锁在可以在较少线程竞争下,减少操作系统调用,减少互斥变量的产生。但在理想情况下,线程很少发生线程竞争,在轻量级锁中,还是会有比较多的CAS操作。在偏向锁中,有一个锁记录(Mark word)标记为偏向,指向当前线程。若该指向不变,则只需要判断记录是否有被切换。如果被切换了,尝试CAS替换指向,后续一直执行同步代码块。当CAS替换指向失败,则说明存在多线程竞争,此时锁会膨胀为轻量级锁。
自旋锁
是锁竞争失败后执行的策略之一,对应的有阻塞的锁。在线程竞争锁失败后,阻塞的锁会把线程阻塞,直到有信号唤起才能继续执行线程,此过程会涉及用户态与系统态的转换,产生性能消耗。而自旋锁在锁竞争失败后,会把线程做自旋,避免线程进入阻塞。在自旋过程中,会不断的尝试去竞争锁。
但如果线程一直自旋都获取不到锁,也会产生很多CPU的性能消耗,所以也有一个自适应的自旋锁(控制自旋的时间)解决这个问题。
更多技术文章、精彩干货,请关注
博客:zackku.com
微信公众号:Zack说码
[](http://qiniu.zackku.com/%E6%89%AB%E7%A0%81_%E6%90%9C%E7%B4%A2%E8%81%94%E5%90%88%E4%BC%A0%E6%92%AD%E6%A0%B7%E5%BC%8F-%E5%BE%AE%E4%BF%A1%E6%A0%87%E5%87%86%E7%BB%BF%E7%89%88.png
Java多线程——锁概念与锁优化的更多相关文章
- Java多线程专题5: JUC, 锁
合集目录 Java多线程专题5: JUC, 锁 什么是可重入锁.公平锁.非公平锁.独占锁.共享锁 可重入锁 ReentrantLock A ReentrantLock is owned by the ...
- Java多线程6:Synchronized锁代码块(this和任意对象)
一.Synchronized(this)锁代码块 用关键字synchronized修饰方法在有些情况下是有弊端的,若是执行该方法所需的时间比较长,线程1执行该方法的时候,线程2就必须等待.这种情况下就 ...
- Java多线程5:Synchronized锁机制
一.前言 在多线程中,有时会出现多个线程对同一个对象的变量进行并发访问的情形,如果不做正确的同步处理,那么产生的后果就是“脏读”,也就是获取到的数据其实是被修改过的. 二.引入Synchronized ...
- Java多线程--基础概念
Java多线程--基础概念 必须知道的几个概念 同步和异步 同步方法一旦开始,调用者必须等到方法调用返回后,才能执行后续行为:而异步方法调用,一旦开始,方法调用就立即返回,调用者不用等待就可以继续执行 ...
- java 多线程总结篇4——锁机制
在开发Java多线程应用程序中,各个线程之间由于要共享资源,必须用到锁机制.Java提供了多种多线程锁机制的实现方式,常见的有synchronized.ReentrantLock.Semaphore. ...
- Java多线程4:synchronized锁机制
脏读 一个常见的概念.在多线程中,难免会出现在多个线程中对同一个对象的实例变量进行并发访问的情况,如果不做正确的同步处理,那么产生的后果就是"脏读",也就是取到的数据其实是被更改过 ...
- Java多线程——深入重入锁ReentrantLock
简述 ReentrantLock 是一个可重入的互斥(/独占)锁,又称为“独占锁”. ReentrantLock通过自定义队列同步器(AQS-AbstractQueuedSychronized,是实现 ...
- java 多线程12 : 无锁 实现CAS原子性操作----原子类
由于java 多线程11:volatile关键字该文讲道可以使用不带锁的情况也就是无锁使变量变成可见,这里就理解下如何在无锁的情况对线程变量进行CAS原子性及可见性操作 我们知道,在并发的环境下,要实 ...
- JAVA多线程提高八:线程锁技术
前面我们讲到了synchronized:那么这节就来将lock的功效. 一.locks相关类 锁相关的类都在包java.util.concurrent.locks下,有以下类和接口: |---Abst ...
随机推荐
- java bigdemical比较大小
版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/qq_33451004/article/details/71247041 java中对bigdimic ...
- HDU1099---数学 | 思维
hdu 1099 Lottery题意:1~n编号的彩票,要买全,等概率条件下平均要买几张.已经买了m张时,买中剩下的概率为1-m/n,则要买的张数为1/(1-m/n)n=2,s=1+1/(1-1/2) ...
- 稀疏编码学习笔记(二)L2范数
L2范数 除了L1范数,还有一种更受宠幸的规则化范数是L2范数: ||W||2.它也不逊于L1范数,它有两个美称,在回归里面,有人把有它的回归叫“岭回归”(Ridge Regression),有人也叫 ...
- 哈希Hash在字符串中的应用_C++
本文含有原创题,涉及版权利益问题,严禁转载,违者追究法律责任 哈希大家都会用撒,字符串显然都会写撒,那么哈希离散化字符串不就懂了?!(XXX的神逻辑,其实原文是:树都晓得吧,数组显然都会开呀,那么恭喜 ...
- [bzoj2049][Sdoi2008]Cave 洞穴勘测——lct
Brief Description 给定一个森林,您需要支持两种操作: 链接两个节点. 断开两个节点之间的链接. Algorithm Design 对于树上的操作,我们现在已经有了树链剖分可以处理这些 ...
- 基于SSM框架web搜索功能的实现
这里适合选用于jsp搭建的网站,数据库采用MySQL 一.HTML <div class="header_search"> <input type="t ...
- 【C++】const、volatile不能修饰没有this指针的成员函数
一般所有的成员函数都只有一个复本,当不同的对象调用成员函数时,为了区分是哪个成员在调用,会传入this指针. 当调用有const.volatile修饰的成员函数时,会相应的传入一个const.vola ...
- CDN缓存(转载)
CDN缓存那些事(转载) 原文地址:http://bbs.qcloud.com/forum.php?mod=viewthread&tid=3775 注:原文全文复制,仅仅作为自己下次学习备份, ...
- 一段js代码的分析
function foo(a){ console.log(a+b); b=a+2; console.log(a+b); } foo(2); foo(3); var b=3; foo(4); 结果是: ...
- python的算法:二分法查找(2)--bisect模块
Python 有一个 bisect 模块,用于维护有序列表.bisect 模块实现了一个算法用于插入元素到有序列表.在一些情况下,这比反复排序列表或构造一个大的列表再排序的效率更高.Bisect 是二 ...