资讯专栏INFORMATION COLUMN

Java锁优化

Bowman_han / 2025人阅读

摘要:一般情况下,可以从两个角度进行锁优化对单个锁算法的优化和对锁粒度的细分。单个锁的优化自旋锁非自旋锁在未获取锁的情况会被阻塞,之后再唤醒尝试获得锁。

Java锁优化

应用程序在并发环境下会产生很多问题,通常情况下,我们可以通过加锁来解决多线程对临界资源的访问问题。但是加锁往往会成为系统的瓶颈,因为加锁和释放锁会涉及到与操作系统的交互,会有很大的性能问题。那么这个时候基于锁的优化手段就显得很重要了。

一般情况下,可以从两个角度进行锁优化:对单个锁算法的优化和对锁粒度的细分。

1. 单个锁的优化 自旋锁:

​ 非自旋锁在未获取锁的情况会被阻塞,之后再唤醒尝试获得锁。而JDK的阻塞和唤醒是基于操作系统实现的,会有系统资源的开销。自旋锁就是线程不停地循环尝试获得锁,而不会将自己阻塞,这样不会浪费系统的资源开销,但是会浪费CPU的资源。所有现在的JDK大部分都是先自旋等待,如果自旋等待一段时间之后还没有获取到锁,就会将当前线程阻塞。

锁消除:

​ 当JVM分析代码时发现某个方法只被单个线程安全访问,而且这个方法是同步方法,那么JVM就会去掉这个方法的锁。

单个锁优化的瓶颈:

​ 对单个锁优化的效果就像提高单个CPU的处理能力一样,最终会由于各个方面的限制而达到一个平衡点,到达这个点之后优化单个锁的对高并发下面锁的优化效果越来越低。所以将一个锁进行粒度细分带来的效果会很明显,如果一个锁保护的代码块被拆分成两个锁来保护,那么程序的效率就大约能够提高到2倍,这个比单个锁的优化带来的效果要明显很多。常见的锁粒度细分技术有:锁分解和锁分段

2. 细分锁粒度

细分锁粒度的目的是降低竞争锁的概率。

2.1 锁分解

锁分解的核心是将无关的代码块,如果在一个方法中有一部分的代码与锁无关,一部分的代码与锁有关,那么可以缩小这个锁的返回,这样锁操作的代码块就会减少,锁竞争的可能性也会减少

缩小锁的范围

缩小锁的范围是指尽量只在必要的地方加锁,不要扩大加锁的范围,就拿单例模式举例,范围大的锁可能将整个方法都加锁了:

class Singleton {
  private Singleton instance;

  private Singleton() {
  }

  // 将整个方法加锁
  public synchronized Singleton getInstance() {
    try {
      Thread.sleep(1000);  //do something
      if(null == instance)
        instance = new Singleton();
    } catch (InterruptedException e) {
      e.printStackTrace();
    }

    return instance;
  }

}

优化后的,只将部分代码加锁:

class Singleton {
  private Singleton instance;

  private Singleton() {
  }

  public Singleton getInstance() {
    try {
      Thread.sleep(1000);  //do something
      // 只对部分代码加锁
      synchronized(this) {
        if(null == instance)
          instance = new Singleton();
      }
    } catch (InterruptedException e) {
      e.printStackTrace();
    }

    return instance;
  }
}
减少锁的粒度

减少锁的粒度是指如果一个锁需要保护多个相互独立的变量,那么可以将一个锁分解为多个锁,并且每个锁保护一个变量,这样就可以减少锁冲突。看一下下面的例子:

class Demo{
  private Set allUsers = new HashSet();
  private Set allComputers = new HashSet();

  //公用一把锁
  public synchronized void addUser(String user){ 
    allUsers.add(user);
  }
  
  public synchronized void addComputer(String computer){
    allComputers.add(computer);
  }
}

缩小锁的粒度后,将一个锁拆分为多个:

class Demo{
  private Set allUsers = new HashSet();
  private Set allComputers = new HashSet();
  
  //分解为两把锁
  public void addUser(String user){ 
    synchronized (allUsers){
      allUsers.add(user);
    }
  }
  
  public void addComputer(String computer){
    synchronized (allComputers){
      allComputers.add(computer);
    }
  }
}

如上的方法把一个锁分解为2个锁时候,采用两个线程时候,大约能够使程序的效率提升一倍。

2.2 锁分段

锁分段和缩小锁的粒度类似,就是将锁细分的粒度更多,比如将一个数组的每个位置当做多带带的锁。JDK8以前ConcurrentHashMap就使用了锁分段技术,它将散列数组分成多个Segment,每个Segment存储了实际的数据,访问数据的时候只需要对数据所在的Segment加锁就行。

参考:

Java锁分解锁分段技术: http://guochenglai.com/2016/0...

ConcurrentHashMap的锁分段技术:https://blog.csdn.net/yansong...

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/69626.html

相关文章

  • Java 虚拟机对优化所做的努力

    摘要:自选锁锁膨胀后,虚拟机为了避免线程真实地在操作系统层面挂起,虚拟机还会在做最后的努力自选锁。 showImg(https://segmentfault.com/img/remote/1460000016159660?w=500&h=333); 作为一款公用平台,JDK 本身也为并发程序的性能绞尽脑汁,在 JDK 内部也想尽一切办法提供并发时的系统吞吐量。这里,我将向大家简单介绍几种 J...

    ralap 评论0 收藏0
  • 值得保存的 synchronized 关键字总结

    摘要:无论是互斥锁,还是自旋锁,在任何时刻,最多只能有一个保持者,也就说,在任何时刻最多只能有一个执行单元获得锁。另外在中引入了自适应的自旋锁。和关键字的总结推荐一 该文已加入开源文档:JavaGuide(一份涵盖大部分Java程序员所需要掌握的核心知识)。地址:https://github.com/Snailclimb... 本文是对 synchronized 关键字使用、底层原理、JD...

    miguel.jiang 评论0 收藏0
  • Synchronized 关键字使用、底层原理、JDK1.6 之后的底层优化以及 和ReenTran

    摘要:使用可以禁止的指令重排,保证在多线程环境下也能正常运行。关键字底层原理总结关键字底层原理属于层面。另外在中引入了自适应的自旋锁。自适应的自旋锁带来的改进就是自旋的时间不在固定了,而是和前一次同一个锁上的自旋时间以及锁的拥有者 【强烈推荐!非广告!】阿里云双11褥羊毛活动:https://m.aliyun.com/act/team1111/#/share?params=N.FF7yxCc...

    Vixb 评论0 收藏0
  • java优化策略

    摘要:前置知识点对象头要了解锁优化策略中的轻量级锁与偏向锁的原理和运作过程,需要先了解虚拟机的对象头部分的内存布局。否则说明这个锁对象已经被其他线程抢占了。 前置知识点:对象头 要了解锁优化策略中的轻量级锁与偏向锁的原理和运作过程,需要先了解Hotspot虚拟机的对象头部分的内存布局。 对象头(摘自《深入理解java虚拟机》) 对象头信息是与对象自身定义的数据无关的额外存储成本 如果对象是数...

    warkiz 评论0 收藏0
  • 浅谈java中的并发控制

    摘要:并发需要解决的问题功能性问题线程同步面临两个问题,想象下有两个线程在协作工作完成某项任务。锁可用于规定一个临界区,同一时间临界区内仅能由一个线程访问。并发的数据结构线程安全的容器,如等。 并发指在宏观上的同一时间内同时执行多个任务。为了满足这一需求,现代的操作系统都抽象出 线程 的概念,供上层应用使用。 这篇博文不打算详细展开分析,而是对java并发中的概念和工具做一个梳理。沿着并发模...

    Gilbertat 评论0 收藏0

发表评论

0条评论

Bowman_han

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<