`
yale
  • 浏览: 356802 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

synchronized的优化

 
阅读更多

在较早版本的JDK中使用synchronized来实现线程安全,但同时使得并发的线程变成顺序执行,对系统并发吞吐能力有极大影响,在JDK1.5以后可以对其进行优化了。

我们先来看看原始的synchronized的使用方法:

悲观锁:

public Object get(Object key) {   
   synchronized(map) {   
      if(map.get(key) == null) {   
         // set some values   
      }   
  
       return map.get(key);   
   }   
}  

 乐观锁:

public Object get(Object key) {   
   Object val = null;   
    if((val = map.get(key) == null) {   
       // if map value is null, add lock measure
       synchronized(map) {   
           if(val = map.get(key) == null) {   
               // set some value to map...   
           }   
        }   
   }   
    //get value 
    return map.get(key);   
} 

 

String.intern:

上述乐观锁中还是不能很好解决大量写冲突问题,比如一个用户必须先创建session,才能进行后续的操作,但由于网络原因创建用户session的请求和后续请求几乎同时达到,而并行线程可能会先处理后续请求。一般情况,需要对用户sessionMap加锁,比如上面的乐观锁。在这种场景下,使用String.inter()是一种更高效的办法,类 String 维护一个字符串池,当调用 intern 方法时,如果池已经包含一个等于此 String 对象的字符串(该对象由 equals(Object) 方法确定),则返回池中的字符串,可见,当String相同时,String.intern()总是返回同一个对象,因此就实现了对同一用户加锁。由于锁的粒度局限于具体用户,使系统获得了最大程度的并发:

public void doSomeThing(String uid) {   
   synchronized(uid.intern()) {   
       // ...   
   }   
} 

 

 

ConcurrentHashMap:

String.inter()的缺陷是类 String 维护一个字符串池是放在JVM perm区的,如果用户数特别多,导致放入字符串池的String不可控,有可能导致OOM错误或者过多的Full GC。怎么样能控制锁的个数,同时减小粒度锁呢?Java ConcurrentHashMap提供了一种很好的方式,将需要加锁的对象分为多个bucket,每个bucket加一个锁,伪代码如下:

Map locks = new Map();   
List lockKeys = new List();   
for(int number : 1 - 10000) {   
   Object lockKey = new Object();   
   lockKeys.add(lockKey);   
    locks.put(lockKey, new Object());   
}   
  
public void doSomeThing(String uid) {   
   Object lockKey = lockKeys.get(uid.hash() % lockKeys.size());   
   Object lock = locks.get(lockKey);         
   synchronized(lock) {   
      // do something   
   }   
}  

上述的做法相当于由全局(只有一个bucket,这个bucket加了锁后,都需要等待)锁变成了一个细粒度(多个bucket,每个bucket加一个锁,即使某个bucket加锁,但是其他bucket并没有加锁,无需等待,这样提高了并发、吞吐量),当然在java.util.concurrent包中还包含一系列的锁来处理同步的问题,比如:ReadWriteLock接口、MuTex等,这些对象在实例化以后都有类似的锁请求、锁超时、锁中断、锁释放的方法来维护锁,当然MuTex还包括了可以在不同的方法中实现锁传递(当获得/释放锁操作不能在同一个方法或者代码块中进行时候,不能使用synchronized块,这就要使用Mutex),这种情况下,要求在持有当前节点锁的同时,获得下一个节点的锁,但是,在获得下一个节点的锁之后,就可以释放当前的锁了!

分享到:
评论

相关推荐

    Java 并发编程学习笔记之Synchronized底层优化

    主要介绍了Java 并发编程学习笔记之Synchronized底层优化的相关资料,主要包含了重量级锁,轻量级锁,偏向锁和其他优化等方面,有需要的小伙伴可以参考下

    Java进阶教程解密JVM视频教程

    手把手视频详细讲解项目开发全过程,需要的小伙伴自行百度网盘下载,链接见附件,永久有效。 课程简介 JVM 是 Java 程序的运行环境,学习 JVM,方能了解 Java 程序是如何被执行的,为进一步...5. synchronized 优化

    12丨多线程之锁优化(上):深入了解Synchronized同步锁的优化方法.html

    12丨多线程之锁优化(上):深入了解Synchronized同步锁的优化方法.html

    sesvc.exe 阿萨德

    从这两个核心方法(get/put)可以看出 1.8 中对大链表做了优化,修改为红黑树之后查询效率直接提高到了 O(logn)。 但是 HashMap 原有的问题也都存在,比如在并发场景下使用时容易出现死循环。 final HashMap, ...

    多线程与高并发编程笔记、源码等

    超全的多线程与高并发的编程笔记,从JVM&JMM角度讲多线程,synchronized优化原理,AQS和线程池等等,需要的童鞋请自行下载!

    java8集合源码分析-JUC:高并发与多线程

    synchronized优化:代码 部分 synchronized底层实现: 早期JDK中,synchronized是重量级的,即需要调用操作系统(OS)来申请锁。 后来改进了,有了锁的升级: Java虚拟机中并没有严格规定synchronized需要如何实现,...

    Lock接口与synchronized关键字

    Lock接口与synchronized关键字在Java并发编程中都是用于实现同步机制的...在性能方面,synchronized通常比Lock接口开销更小,因为它是JVM内置的支持,优化程度更高。然而,在高度竞争的并发场景下,Lock接口可能会表现

    java关键字Synchronized详解

    为了避免锁膨胀,Java提供了一种称为“偏向锁”的优化策略。偏向锁的主要目的是减少锁竞争,提高并发性能。当一个对象首次被创建时,JVM会自动为其分配偏向锁。此时,如果其他线程试图获取该对象的锁,JVM会将对象头...

    Java 之 synchronized实现机制(monitor)及其优化(CAS操作、Java对象头、偏向锁).docx

    使用内建锁(synchronized)进行同步,关键在于要获取指定锁对象monitor对象,当线程获取monitor后才能继续向下执行,否则就只能等待。这个获取过程是互斥的,即同一时刻只有一个线程能够获取到对象的monitor监视器...

    Java中synchronized实现原理详解

    主要介绍了Java中synchronized实现原理详解,涉及synchronized实现同步的基础,Java对象头,Monitor,Mark Word,锁优化,自旋锁等相关内容,具有一定借鉴价值,需要的朋友可以参考下。

    第16讲synchronized底层如何实现?什么是锁...1

    极客时间 | Java核心技术36讲所谓锁的升级、降级,就是 JVM 优化 synchronized 运行的机制,当 JVM 检测到不同的竞争状况时,会自动切换

    第16讲 synchronized底层如何实现?什么是锁的升级、降级?1

    所谓锁的升级、降级,就是 JVM 优化 synchronized 运行的机制,当 JVM 检测到不同的竞争状况时,会自动切换到适合的锁实现,这种切换就是锁的升级

    Tomcat的三种模式及并发优化

    Tomcat的三种模式及并发优化Tomcat的三种模式及并发优化

    Android开发性能优化总结

    一. 加载 预加载:1.反射注解框架Reflect信息,在Application内多线程预加载至缓存。...2. 并发操作多用读写锁,少用synchronized,Android虚拟机Art直到Android6.0为止尚未对synchronized做CAS优化,而sy

    多线程下的单例模式优化

    这是一个关于多线程下的单例模式优化代码。public class Singleton { private static Singleton instance; private Singleton (){ } public static Singleton getInstance(){ //对获取实例的方法进行同步 if...

    诺基亚移动无线参数详细解释

    诺基亚移动无线参数详细解释 ...第二部分:网络参数优化 147 一. TCH掉话参数优化 148 二. TCH拥塞参数优化 158 三. SDCCH拥塞参数优化 164 四. HO失败率参数优化 168 五. BOOSTER专题 175 六. 微蜂窝专题 185

    jvm细节探索之synchronized及实现问题分析

    主要介绍了jvm细节探索之synchronized及实现问题分析,涉及synchronized的字节码表示,JVM中锁的优化,对象头的介绍等相关内容,具有一定借鉴价值,需要的朋友可以参考下。

    Java理论与实践:Mustang中的同步优化

    当两个线程都想访问共享的易变变量时,这两个线程不仅必须使用同步,而且如果它们正在使用synchronized块,那么这些synchronized 块还必须使用同一个锁对象。本文还介绍了JVM对于竞争锁请求和非竞争锁请求有不同的...

    Java中ReentrantLock的使用.docx

    重入锁ReentrantLock 相对来说是synchronized、Object.wait()和Object.notify()方法的替代品(或者说是增强版),在JDK5.0的早期版本,重入锁的性能远远好于...,JDK在synchronized上做了大量的优化...

    java并发编程-AQS和JUC实战

    synchronized,但从JDK6.0开始,JDK在synchronized上做了⼤量的优化,使得两者的性能差距并 不⼤。重⼊锁对逻辑控制的灵活性要远远好于synchronized。 之所以称之为重⼊锁,就是⼀个线程允许反复进⼊。当然,这⾥的...

Global site tag (gtag.js) - Google Analytics