为了性能与使用的场景,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多线程——锁概念与锁优化的更多相关文章

  1. Java多线程专题5: JUC, 锁

    合集目录 Java多线程专题5: JUC, 锁 什么是可重入锁.公平锁.非公平锁.独占锁.共享锁 可重入锁 ReentrantLock A ReentrantLock is owned by the ...

  2. Java多线程6:Synchronized锁代码块(this和任意对象)

    一.Synchronized(this)锁代码块 用关键字synchronized修饰方法在有些情况下是有弊端的,若是执行该方法所需的时间比较长,线程1执行该方法的时候,线程2就必须等待.这种情况下就 ...

  3. Java多线程5:Synchronized锁机制

    一.前言 在多线程中,有时会出现多个线程对同一个对象的变量进行并发访问的情形,如果不做正确的同步处理,那么产生的后果就是“脏读”,也就是获取到的数据其实是被修改过的. 二.引入Synchronized ...

  4. Java多线程--基础概念

    Java多线程--基础概念 必须知道的几个概念 同步和异步 同步方法一旦开始,调用者必须等到方法调用返回后,才能执行后续行为:而异步方法调用,一旦开始,方法调用就立即返回,调用者不用等待就可以继续执行 ...

  5. java 多线程总结篇4——锁机制

    在开发Java多线程应用程序中,各个线程之间由于要共享资源,必须用到锁机制.Java提供了多种多线程锁机制的实现方式,常见的有synchronized.ReentrantLock.Semaphore. ...

  6. Java多线程4:synchronized锁机制

    脏读 一个常见的概念.在多线程中,难免会出现在多个线程中对同一个对象的实例变量进行并发访问的情况,如果不做正确的同步处理,那么产生的后果就是"脏读",也就是取到的数据其实是被更改过 ...

  7. Java多线程——深入重入锁ReentrantLock

    简述 ReentrantLock 是一个可重入的互斥(/独占)锁,又称为“独占锁”. ReentrantLock通过自定义队列同步器(AQS-AbstractQueuedSychronized,是实现 ...

  8. java 多线程12 : 无锁 实现CAS原子性操作----原子类

    由于java 多线程11:volatile关键字该文讲道可以使用不带锁的情况也就是无锁使变量变成可见,这里就理解下如何在无锁的情况对线程变量进行CAS原子性及可见性操作 我们知道,在并发的环境下,要实 ...

  9. JAVA多线程提高八:线程锁技术

    前面我们讲到了synchronized:那么这节就来将lock的功效. 一.locks相关类 锁相关的类都在包java.util.concurrent.locks下,有以下类和接口: |---Abst ...

随机推荐

  1. codeforces 1015B

    B. Obtaining the String time limit per test 1 second memory limit per test 256 megabytes input stand ...

  2. BZOJ1040 骑士 基环外向树

    1040: [ZJOI2008]骑士 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 6421  Solved: 2544[Submit][Status ...

  3. 使用bcrypt进行加密的简单实现

    Bcrypt百度百科: bcrypt,是一个跨平台的文件加密工具.由它加密的文件可在所有支持的操作系统和处理器上进行转移.它的口令必须是8至56个字符,并将在内部被转化为448位的密钥. 除了对您的数 ...

  4. leetcode-501. Find Mode in Binary Search Tree

    Given a binary search tree (BST) with duplicates, find all the mode(s) (the most frequently occurred ...

  5. eclipse怎样快速的给代码段添加try catch

    打开要进行异常处理的java代码页面. 选中要添加try..catch的代码段,然后点击鼠标右键,选择[Sourround With]选项. 然后选择[Try/Catch Block]或者[6 try ...

  6. 在liberty中通过LTPA设置单点登录

    不要忘了下面的设置,参考: https://www-01.ibm.com/support/knowledgecenter/was_beta_liberty/com.ibm.websphere.wlp. ...

  7. unity下的Line of Sight(LOS)的绘制

    先说说什么是Linf of Sight.在很多RTS游戏中,单位与单位之间的视野关系经常会受到障碍物遮挡.Line of Sight指的就是两个物体之间是否没有障碍物遮挡. 比如在dota中,玩家的视 ...

  8. bzoj 1297 矩阵乘法变形

    首先对于矩阵乘法的功能有很多,记得有篇论文叫矩阵乘法在信息学竞赛中的应用,里面详细介绍了矩阵的 作用 其中一个就是求图的固定时间方案数,也就是给定一张图,每两个点之间由一条边长为1的边相连, 求任意两 ...

  9. echarts图表自适应浏览器窗口的大小

    echarts问题描述 当浏览器窗口发生变化时,echarts图表未能自适应浏览器的变化,产生如下的效果 解决方案 在$(function(){}中添加 window.onresize = funct ...

  10. nginx启动脚本(class练习)

    说明:使用类的方式编写程序启动脚本(练习) 1 #!/usr/bin/env python import sys import os from subprocess import Popen,PIPE ...