在较早版本的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实现线程同步的关键机制,其在JDK1.6之后进行了大量的优化,包括引入了轻量级锁和偏向锁,以提升并发性能。以下是关于这些优化的详细解释: **一、重量级锁** 重量级锁是基于...
手把手视频详细讲解项目开发全过程,需要的小伙伴自行百度网盘下载,链接见附件,永久有效。 课程简介 JVM 是 Java 程序的运行环境,学习 JVM,方能了解 Java 程序是如何被执行的,为进一步...5. synchronized 优化
4. **编译器优化**:`volatile`标记的变量不会被编译器优化,以保证其可见性,而`synchronized`标记的变量可能会被编译器优化。 5. **线程阻塞**:使用`synchronized`时,当一个线程持有锁时,其他试图获取该锁的...
“synchronized优化原理”是一个重要的知识点,synchronized是Java中用于控制并发的关键词,它可以保证代码块或方法在同一时间只被一个线程访问。学习这个主题,开发者将了解其工作原理、锁的升级机制以及如何有效...
《深入理解Java中的synchronized关键字》 在Java编程语言中,`synchronized`关键字是用于实现线程同步的重要工具,它的本质在于确保多线程环境下的数据一致性与安全性。通过`synchronized`,我们可以控制对共享资源...
### Synchronized关键字在Java中的应用 #### 概述 `synchronized`是Java语言中的一个关键字,主要用于实现线程同步,防止多个线程同时访问共享资源而导致的数据不一致问题。通过`synchronized`关键字,开发者可以...
3. **synchronized优化**:规范对synchronized块和方法的实现进行了优化,提升了其性能,同时保持了原有的互斥和可见性保证。 4. **最终变量的保证**:JSR133确保了final字段在构造函数完成后对其他线程的可见性,...
`synchronized`在早期的Java版本中性能较差,但随着JVM的优化,现在的`synchronized`在大多数情况下性能已经很好。然而,在需要高度定制的同步策略时,`Lock`接口可能是更好的选择。 总结,`synchronized`是Java多...
Java中的`synchronized`关键字是多线程编程中用于同步控制的关键元素,它的主要目标是解决并发环境下多个...在编写多线程程序时,开发者应该根据具体情况选择合适的同步策略,避免不必要的同步控制,以优化程序的性能。
10. **Synchronized优化**: JDK 1.5对synchronized关键字进行了优化,如偏向锁和轻量级锁,提高了多线程环境下的性能。 11. **内存模型和并发API(Memory Model and Concurrency API)**: Java内存模型(JMM)...
- 从Java 5开始,JVM对`synchronized`进行了很多优化,如偏向锁、轻量级锁、自旋锁等,使得在低负载情况下,同步操作的性能得到了显著提升。 9. **示例代码分析**: 根据提供的文件名,`GenerateCode.java`可能...
- **ConcurrentHashMap**:在并发环境下提供线程安全,采用分段锁策略,JDK1.8后使用CAS和Synchronized优化。 **4. JUC(Java并发工具包)** - **Volatile**:保证可见性,但不保证原子性,适合简单变量共享。 - **...
12丨多线程之锁优化(上):深入了解Synchronized同步锁的优化方法.html
性能方面,早期的Java版本中,synchronized的性能相对较差,但在后续的优化中,synchronized在许多场景下的表现已经接近或优于ReentrantLock。然而,在高竞争的场景下,ReentrantLock通常能提供更好的性能,因为它...
- 随着 Java 版本的升级,JVM 对 synchronized 的优化使得其性能得到了显著提升。 #### 二、ThreadLocal机制详解 **ThreadLocal** 提供了一种线程本地存储的解决方案,为每个线程创建独立的副本,避免了线程间的...
五、synchronized的局限性与优化 虽然`synchronized`提供了线程安全,但可能导致性能问题,因为它会导致线程阻塞。为了解决这个问题,Java引入了`Lock`接口及其实现,如`ReentrantLock`,它提供了更灵活的控制,...
可以简单理解 lock 比 synchronized 更加优秀和合理,是前者的优化版。 不同点 ---------- ### 1. 语法结构 synchronized 是 Java 中的关键字,有其语言的内置性。lock 则不是 Java 的关键字,它是 Java 的一个...
综上,`synchronized`关键字是Java中实现线程同步的关键,通过多种优化策略提升了并发性能,并提供了不同级别的锁机制来适应不同的场景需求。理解并熟练掌握`synchronized`的使用对于编写高性能、线程安全的Java程序...
然而,随着JVM的不断优化,对于无竞争的同步操作,其性能成本已经大大降低。 4. **局限性**: - `synchronized`无法中断正在等待获取锁的线程。 - 锁的释放与获取必须在相同的堆栈帧中进行,这在某些场景下可能...
未来的研究方向可能包括进一步优化模型结构以提高识别精度,探索更多应用场景以及与其他模态(如音频)相结合的可能性。此外,还可以考虑开发更加鲁棒的特征提取方法,以适应不同环境和个体差异。