多线程之--synchronized 和reentrantlock的优缺点
多线程之--2种JAVA乐观锁的比较( NonfairSync VS. FairSync)
本文从成员函数和锁的获取这2个角度, 比较这2种锁. 发现区别其实不大.只有在阻塞队列为0的时候才有些许区别. 如果分析的不对,请斧正.
稍后如果有时间,准备使用实例来测试一下.
成员函数的比较
从下面的截图可以清晰的看到除了构造函数不一样,其他的都一样.重点是都只有lock() 和 tryAcquire(), 那从另一个角度也可以说明,只有锁的获取是不一样的,锁的释放和从阻塞队列选取线程来激活的方法是一样的.
锁的获取
下面是相关的源码,然后通过三种场景比较区别
- //NonfairSync
- final void lock() {
- if (compareAndSetState(0, 1))
- setExclusiveOwnerThread(Thread.currentThread());
- else
- acquire(1);
- }
- //FairSync
- final void lock() {
- acquire(1);
- }
1)在资源没有被占用的情况下:
非公平锁是: 先state+1,然后直接得到锁,
而公平锁则是: 先尝试去获取锁,如果得到了锁则state+1.
2)如果是同一线程,再次申请锁.
两种锁,表现基本一致,可以参考下面的代码块. (只是这段代码块在不同函数中)
- <span style="font-size: 1em; line-height: 1.5;">//NonfairSync : Sync.</span>nonfairTryAcquire()<span style="font-size: 1em; line-height: 1.5;">
- //FairSync</span> : FairSync.tryAcquire()
- else if (current == getExclusiveOwnerThread()) {
- int nextc = c + acquires;
- if (nextc < 0) // overflow
- throw new Error("Maximum lock count exceeded");
- setState(nextc);
- return true;
- }
3)如果是不同线程申请锁:
从业务逻辑来看,公平锁和非公平锁唯一的区别就是需要判断当前线程是不是链表头.但是一直有一点不明白的,在c==0的情况下, 不是就可以说明已经是表头了吗? 为什么还要检查 isFirst(current). compareAndSetState(0, acquires) 也可以保证在并发的情况下只有state=0才能获取锁.
- //FairSync : FairSync.tryAcquire()
- if (c == 0) {
- if (isFirst(current) && //唯一的区别
- compareAndSetState(0, acquires)) {
- setExclusiveOwnerThread(current);
- return true;
- }
- }
总结
非公平锁,和公平锁只有在state=0的时候,业务逻辑不一样.
- 在stage=0的时候,非公平锁是直接获取锁,没有维护等待队列.
- 在stage=0的时候, 公平锁依然需要检查当前线程是否是等待队列的第一个.
相关推荐
在Java中,`java.util.concurrent.atomic`包下的原子变量类如AtomicInteger、AtomicLong等,使用了CAS算法来实现乐观锁。 **版本号机制**是乐观锁的一种实现方式,通过添加一个版本号字段来跟踪数据的修改。当读取...
java乐观锁是一种乐观的并发控制机制,它认为线程冲突的可能性小,比较乐观,直接去操作数据,如果发现数据已经被更改(通过版本号控制),则不更新数据,再次去重复所需操作,知道没有冲突(使用递归算法)。...
在Java中,java.util.concurrent.atomic包下的原子变量类使用了CAS算法,提供了一种乐观锁的实现方式。 关于乐观锁的实现,版本号机制和CAS算法各有其使用场景。版本号机制简单直观,易于理解和实现,适用于对冲突...
乐观锁和悲观锁是数据库和并发编程中常见的两种锁机制,它们主要用于解决多线程环境下的数据一致性问题。在Java面试中,理解这两种锁的概念、工作原理以及适用场景是非常重要的。 乐观锁是一种假设大多数情况下不会...
本文将深入探讨这两种锁机制,帮助你更好地理解和准备相关的面试问题。 首先,我们来理解悲观锁。悲观锁的名字来源于其对并发操作的态度,它假设数据在任何时候都可能被其他事务修改,因此在读取数据时会立即加锁,...
每种锁都有其特性和使用场景,我们需要根据具体情况选择合适的锁机制。 例如,在更新数据时,我们可以使用乐观锁来检测数据是否被修改过,如果被修改过,则进行重试。如果在多线程情况下,我们可以使用悲观锁来锁定...
悲观锁和乐观锁各有优缺点,选择哪种锁机制取决于具体的应用场景和需求。悲观锁适合数据修改频繁且对数据一致性要求较高的场景;而乐观锁适用于数据修改较少且并发量较大的场景。在实际应用中,可以根据具体情况灵活...
Java中,`java.util.concurrent.atomic`包下的原子变量类如AtomicInteger、AtomicLong等利用CAS(Compare and Swap)算法实现了乐观锁。 - **悲观锁**假设并发环境下数据频繁被修改,因此在读取时就会上锁,确保...
读写锁是专为读多写少的场景设计的一种锁策略,它允许多个读操作并行执行,但写操作与读操作、写操作之间是互斥的。在Java中,ReentrantReadWriteLock类是读写锁的实现,它包含两个锁:读锁(共享锁)和写锁(独占锁...
1. db2java.jar:这个文件包含了IBM DB2数据库的Java Native Interface (JNI) 驱动,也称为Type 2驱动。JNI驱动允许Java代码调用本地操作系统接口,从而实现与数据库的低级别交互。这种驱动适用于那些需要利用操作...
<Call Stack = DEBUG_FRAME = org.apache.axis2.util.JavaUtils.callStackToString(JavaUtils.java:564) DEBUG_FRAME = org.apache.axis2.description.ParameterIncludeImpl.debugParameterAdd(ParameterIncludeImpl...
java.applet java.awt java.awt.color java.awt.datatransfer java.awt.dnd java.awt.event java.awt.font java.awt.geom java.awt.im java.awt.im.spi java.awt.image java.awt.image.renderable java....
【Hibernate乐观锁与悲观锁详解】 在开发过程中,尤其是在并发环境下,确保数据的一致性和完整性至关重要。...在使用Hibernate时,理解并正确配置这两种锁机制,能有效避免并发环境下的数据不一致性问题。
这个压缩包 "selenium-java-2.47.1.zip" 包含了Selenium的Java版本,具体是2.47.1的更新,发布于2015年8月。这个版本在当时是一个稳定且广泛使用的版本,它提供了丰富的API,支持多种浏览器,并且可以与各种测试框架...
本文将深入探讨标题和描述中提及的各种锁,包括乐观锁、悲观锁、分布式锁、可重入锁、互斥锁、读写锁、分段锁、类锁以及行级锁。 1. **乐观锁**:乐观锁假设多线程环境中的冲突较少,所以在读取数据时不加锁,只有...
1、下载WSDL2JAVA.rar包,其中包含activation.jar,axis-ant.jar,axis.jar,commons- discovery-0.2.jar,commons-logging-1.0.4.jar,jaxrpc.jar,log4j- 1.2.8.jar,mail.jar,saaj.jar,wsdl4j-1.5.1.jar。...
找了好久,终于找到了,java刷新同步获取网络资源
本书可作为《轻量级java ee企业应用实战》的姊妹篇,介绍了Java EE规范的三大主要规范JSF(JavaServer Faces)、EJB 3(Enterprise JavaBeans 3)和JPA(Java Persistence API),并以ejb 3+jpa为基础来构建Java EE...
介绍数据库事务的定义和事务带来的问题,详细讲解乐观锁与悲观锁的区别
6. 锁:CAS、乐观锁与悲观锁、数据库相关锁机制、分布式锁、偏向锁、轻量级锁、重量级锁、monitor、锁优化、锁消除、锁粗化、自旋锁、可重入锁、阻塞锁、死锁 7. happens-before、编译器指令重排和 CPU 指令重...