`
flyfoxs
  • 浏览: 298098 次
  • 性别: Icon_minigender_1
  • 来自: 合肥
社区版块
存档分类
最新评论

2种JAVA乐观锁的比较( NonfairSync VS. FairSync)

 
阅读更多
 

多线程之--2种办法让HashMap线程安全

多线程之--synchronized 和reentrantlock的优缺点

多线程之--2种JAVA乐观锁的比较( NonfairSync VS. FairSync)

 

本文从成员函数和锁的获取这2个角度, 比较这2种锁. 发现区别其实不大.只有在阻塞队列为0的时候才有些许区别. 如果分析的不对,请斧正.

 

稍后如果有时间,准备使用实例来测试一下.

 

成员函数的比较

从下面的截图可以清晰的看到除了构造函数不一样,其他的都一样.重点是都只有lock() 和 tryAcquire(), 那从另一个角度也可以说明,只有锁的获取是不一样的,锁的释放和从阻塞队列选取线程来激活的方法是一样的.



 
 

锁的获取

下面是相关的源码,然后通过三种场景比较区别

 

Java代码 
  1. //NonfairSync  
  2.   
  3.         final void lock() {  
  4.             if (compareAndSetState(01))  
  5.                 setExclusiveOwnerThread(Thread.currentThread());  
  6.             else  
  7.                 acquire(1);  
  8.         }  
  9.   
  10.   
  11. //FairSync  
  12.         final void lock() {  
  13.             acquire(1);  
  14.         }  

 

 

 

1)在资源没有被占用的情况下:

非公平锁是: 先state+1,然后直接得到锁,

而公平锁则是: 先尝试去获取锁,如果得到了锁则state+1.

 

2)如果是同一线程,再次申请锁.

两种锁,表现基本一致,可以参考下面的代码块. (只是这段代码块在不同函数中)

 

Java代码 
  1. <span style="font-size: 1em; line-height: 1.5;">//NonfairSync : Sync.</span>nonfairTryAcquire()<span style="font-size: 1em; line-height: 1.5;">  
  2. //FairSync</span> : FairSync.tryAcquire()           
  3.   
  4.             else if (current == getExclusiveOwnerThread()) {  
  5.                 int nextc = c + acquires;  
  6.                 if (nextc < 0// overflow  
  7.                     throw new Error("Maximum lock count exceeded");  
  8.                 setState(nextc);  
  9.                 return true;  
  10.             }  
 

 3)如果是不同线程申请锁:

从业务逻辑来看,公平锁和非公平锁唯一的区别就是需要判断当前线程是不是链表头.但是一直有一点不明白的,在c==0的情况下, 不是就可以说明已经是表头了吗? 为什么还要检查 isFirst(current). compareAndSetState(0, acquires) 也可以保证在并发的情况下只有state=0才能获取锁.

 

Java代码 
  1. //FairSync : FairSync.tryAcquire()             
  2.           if (c == 0) {  
  3.                if (isFirst(current) && //唯一的区别  
  4.                    compareAndSetState(0, acquires)) {  
  5.                    setExclusiveOwnerThread(current);  
  6.                    return true;  
  7.                }  
  8.            }  
 

 

 

总结

非公平锁,和公平锁只有在state=0的时候,业务逻辑不一样. 

  • 在stage=0的时候,非公平锁是直接获取锁,没有维护等待队列.
  • 在stage=0的时候, 公平锁依然需要检查当前线程是否是等待队列的第一个.

 

 

  • 大小: 14.9 KB
0
0
分享到:
评论

相关推荐

    mysql的乐观锁、悲观锁.md

    java,乐观锁,悲观锁详解释

    JAVA架构面试专题_面试必备之乐观锁与悲观锁.pdf

    在Java中,`java.util.concurrent.atomic`包下的原子变量类如AtomicInteger、AtomicLong等,使用了CAS算法来实现乐观锁。 **版本号机制**是乐观锁的一种实现方式,通过添加一个版本号字段来跟踪数据的修改。当读取...

    java乐观锁原理与实现案例分析

    java乐观锁是一种乐观的并发控制机制,它认为线程冲突的可能性小,比较乐观,直接去操作数据,如果发现数据已经被更改(通过版本号控制),则不更新数据,再次去重复所需操作,知道没有冲突(使用递归算法)。...

    面试必备之乐观锁与悲观锁.pdf

    在Java中,java.util.concurrent.atomic包下的原子变量类使用了CAS算法,提供了一种乐观锁的实现方式。 关于乐观锁的实现,版本号机制和CAS算法各有其使用场景。版本号机制简单直观,易于理解和实现,适用于对冲突...

    面试必备之乐观锁与悲观锁.zip

    乐观锁和悲观锁是数据库和并发编程中常见的两种锁机制,它们主要用于解决多线程环境下的数据一致性问题。在Java面试中,理解这两种锁的概念、工作原理以及适用场景是非常重要的。 乐观锁是一种假设大多数情况下不会...

    面试必备之乐观锁与悲观锁.rar

    本文将深入探讨这两种锁机制,帮助你更好地理解和准备相关的面试问题。 首先,我们来理解悲观锁。悲观锁的名字来源于其对并发操作的态度,它假设数据在任何时候都可能被其他事务修改,因此在读取数据时会立即加锁,...

    JAVA中锁的解决方案.docx

    每种锁都有其特性和使用场景,我们需要根据具体情况选择合适的锁机制。 例如,在更新数据时,我们可以使用乐观锁来检测数据是否被修改过,如果被修改过,则进行重试。如果在多线程情况下,我们可以使用悲观锁来锁定...

    Java 中的悲观锁和乐观锁的实现

    悲观锁和乐观锁各有优缺点,选择哪种锁机制取决于具体的应用场景和需求。悲观锁适合数据修改频繁且对数据一致性要求较高的场景;而乐观锁适用于数据修改较少且并发量较大的场景。在实际应用中,可以根据具体情况灵活...

    彻底理解Java中的各种锁.pdf

    读写锁是专为读多写少的场景设计的一种锁策略,它允许多个读操作并行执行,但写操作与读操作、写操作之间是互斥的。在Java中,ReentrantReadWriteLock类是读写锁的实现,它包含两个锁:读锁(共享锁)和写锁(独占锁...

    Java 面经手册·小傅哥.pdf

    这是一本以面试题为入口讲解 Java 核心内容的技术书籍,书中内容极力的向你证实代码是对数学...2. 想阅读 Java 核心源码,但总感觉看不懂的 3. 看了太多理论,但没有实践验证的 4. 求职面试,总被面试题搞的死去活来的

    java锁详解.pdf

    2. 锁的分类:synchronized 锁可以分为轻量级锁、偏向锁和重量级锁三种。 3. 轻量级锁:轻量级锁是 synchronized 锁的一种实现方式,使用 CAS 操作来更新对象的 Mark Word。轻量级锁的加锁过程可以分为三步:创建锁...

    Java并发篇乐观锁,悲观锁,自旋锁

    本文主要讨论了四种锁类型:乐观锁、悲观锁、自旋锁以及Java中的synchronized同步锁,并深入解析了synchronized锁的内部机制,包括其核心组件、实现方式以及锁的状态。 1. **乐观锁**:乐观锁假设在多线程环境下,...

    selenium-java-2.47.1.zip

    这个压缩包 "selenium-java-2.47.1.zip" 包含了Selenium的Java版本,具体是2.47.1的更新,发布于2015年8月。这个版本在当时是一个稳定且广泛使用的版本,它提供了丰富的API,支持多种浏览器,并且可以与各种测试框架...

    java keystore导出.pfx .key .crt 私钥

    Java KeyStore文件转换为...Java Runtime的目录,指包含Java.exe和keytool.exe的目录,如: c:\progra~1\Java\jre1.5.0_06\bin 例如: JKS2PFX server.jks 123456 tomcat exportfile c:\progra~1\Java\jre1.5.0_06\bin

    各种锁汇总,乐观锁、悲观锁、分布式锁、可重入锁、互斥锁、读写锁、分段锁、类锁、行级锁等

    本文将深入探讨标题和描述中提及的各种锁,包括乐观锁、悲观锁、分布式锁、可重入锁、互斥锁、读写锁、分段锁、类锁以及行级锁。 1. **乐观锁**:乐观锁假设多线程环境中的冲突较少,所以在读取数据时不加锁,只有...

    Java开发技术大全(500个源代码).

    narrowingConversion_2.java 缩减转换引发错误示例2 notMultipleOfThree.java 把100-200之间不能被3整除的数输出 outputByDoWhile.java 用while循环随机输出数据 outputByWhile.java 用do~while循环随机输出数据...

    Java网络编程第三版.pdf

    2. **I/O与NIO**:Java的I/O流系统是网络编程的基础,包括字节流、字符流、对象流等。此外,非阻塞I/O(NIO)的引入为高性能网络应用提供了可能,如Selector和Channel的概念。 3. **多线程与并发**:在网络编程中,...

    乐观锁与悲观锁

    介绍数据库事务的定义和事务带来的问题,详细讲解乐观锁与悲观锁的区别

    javacv-core-1.3.zip

    javacv-core-1.3.zip包含javacv.jar,javacpp.jar和javacv-platform.jar三个核心jar包

    mysql-connector-java-5.1.40-bin.jar连接器

    JDBC是Sun Microsystems(现为Oracle公司)为Java编程语言设计的一套标准API,它的主要功能是为Java开发者提供一种统一的方式来访问各种不同类型的数据库,而无需关心具体的数据库厂商。通过JDBC,开发者可以编写...

Global site tag (gtag.js) - Google Analytics