synchronized和lock(reentrantlock) 区别

From:

http://blog.csdn.net/ningguixin/article/details/23950521

synchronized是托管给JVM执行的,而lock是java写的控制锁的代码。在Java1.5中,synchronize是性能低效的。因为这是一个重量级操作,需要调用操作接口,导致有可能加锁消耗的系统时间比加锁以外的操作还多。相比之下使用Java提供的Lock对象,性能更高一些。但是到了Java1.6,发生了变化。synchronize在语义上很清晰,可以进行很多优化,有适应自旋,锁消除,锁粗化,轻量级锁,偏向锁等等。导致在Java1.6上synchronize的性能并不比Lock差。官方也表示,他们也更支持synchronize,在未来的版本中还有优化余地。

说到这里,还是想提一下这2中机制的具体区别。据我所知,synchronized原始采用的是CPU悲观锁机制,即线程获得的是独占锁。独占锁意味着其他线程只能依靠阻塞来等待线程释放锁。而在CPU转换线程阻塞时会引起线程上下文切换,当有很多线程竞争锁的时候,会引起CPU频繁的上下文切换导致效率很低。

而Lock用的是乐观锁方式。所谓乐观锁就是,每次不加锁而是假设没有冲突而去完成某项操作,如果因为冲突失败就重试,直到成功为止。乐观锁实现的机制就是CAS操作(Compare and Swap)。我们可以进一步研究ReentrantLock的源代码,会发现其中比较重要的获得锁的一个方法是compareAndSetState。这里其实就是调用的CPU提供的特殊指令。

现代的CPU提供了指令,可以自动更新共享数据,而且能够检测到其他线程的干扰,而 compareAndSet() 就用这些代替了锁定。这个算法称作非阻塞算法,意思是一个线程的失败或者挂起不应该影响其他线程的失败或挂起的算法。

我也只是了解到这一步,具体到CPU的算法如果感兴趣的读者还可以在查阅下,如果有更好的解释也可以给我留言,我也学习下。

 

 

1.某个线程在等待一个锁的控制权的这段时间需要中断
2.需要分开处理一些wait-notify,ReentrantLock里面的Condition应用,能够控制notify哪个线程
3.具有公平锁功能,每个到来的线程都将排队等候

--------------------以上引用http://blog.csdn.net/natian306/article/details/18504111

1,3网上都有很明确的解释。

 

下面看下2:下面是引用java api对condtition的的描述的一段代码。wait与notifiy 。

wait:Causes the current thread to wait until either another thread invokes thenotify() method or thenotifyAll() method for this object, or a specified amount of time has elapsed.

 

nofity:Wakes up a single thread that is waiting on this object's monitor. If any threads are waiting on this object, one of them is chosen to be awakened. The choice is arbitrary and occurs at the discretion of the implementation. A thread waits on an object's monitor by calling one of the wait methods.

Nofity只能唤醒这个对象已经调用了wait的线程。 而下面的condition可以根据条件来控制唤醒那个线程。 下面例子分别为可以控制唤醒notFull 与 notEmpty 。

  1. <p>class BoundedBuffer {  
  2.  final Lock lock = new ReentrantLock();  
  3.  final Condition notFull = lock.newCondition();  
  4.  final Condition notEmpty = lock.newCondition();  
  5.  final Object[] items = new Object[100];  
  6.  int putptr, takeptr, count;</p><p> public void put(Object x) throws InterruptedException {  
  7.   lock.lock();  
  8.   try {  
  9.    while (count == items.length)  
  10.     notFull.await();  
  11.    items[putptr] = x;  
  12.    if (++putptr == items.length)  
  13.     putptr = 0;  
  14.    ++count;  
  15.    notEmpty.signal();  
  16.   } finally {  
  17.    lock.unlock();  
  18.   }  
  19.  }</p><p> public Object take() throws InterruptedException {  
  20.   lock.lock();  
  21.   try {  
  22.    while (count == 0)  
  23.     notEmpty.await();  
  24.    Object x = items[takeptr];  
  25.    if (++takeptr == items.length)  
  26.     takeptr = 0;  
  27.    --count;  
  28.    notFull.signal();  
  29.    return x;  
  30.   } finally {  
  31.    lock.unlock();  
  32.   }  
  33.  }  
  34. }  
  35. </p> 



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值