`
flyfoxs
  • 浏览: 293913 次
  • 性别: 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
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics