现在的位置: 首页 > 综合 > 正文

java.util.concurrent(JUC)的研究–》锁机制–》Lock与ReentrantLock

2016年10月15日 ⁄ 综合 ⁄ 共 1678字 ⁄ 字号 评论关闭

从本文开始我们对JUC中比较重要的锁机制进行研究,下面我们来看下java.util.concurrent.locks.Lock接口和其实现类ReentrantLock。

 

互斥锁--Lock接口及其实现类ReentrantLock:

所谓互斥锁, 指的是一次最多只能有一个线程持有的锁. 在jdk1.5之前, 我们通常使用synchronized机制控制多个线程对共享资源的访问。而现在Lock提供了比synchronized机制更广泛灵活的锁定操作。

对于Lock与synchronized的区别:

1.Lock能够完成synchronized所实现的所有功能,并且提供了多样化的同步,比如有时间限制的同步,可以被Interrupt的同步(synchronized的同步是不能Interrupt的)等。

     如果使用 synchronized ,如果A不释放,B将一直等下去,不能被中断。

     如果 使用ReentrantLock,如果A不释放,可以使B在等待了足够长的时间以后,中断等待,而干别的事情。

2、synchronized是在JVM层面上实现的,不但可以通过一些监控工具监控synchronized的锁定,而且在代码执行时出现异常,JVM会自动释放锁定。但Lock不能,只能手动释放,并且在finally从句中unLock()释放。

3、性能:在jdk1.5中Synchronized是使用的独占悲观锁,资源竞争不激烈的情况下synchronized性能略高,资源竞争激烈的情况下性能要远低于Lock。jdk1.6以后synchronized和lock一样都是使用CAS乐观锁操作,所以性能差不多,对于具体使用哪一个要看具体的系统应用需要,Synchronized相对简单易用,若需要精细的灵活控制则可以考虑选择lock。

 

Lock的主要方法介绍:

    void lock(); ---获取锁。执行此方法时,如果锁处于空闲状态,当前线程将获取到锁。相反,如果锁已经被其他线程持有,将禁用当前线程并处于休眠状态,直到当前线程获取到锁。

01.    Lock lock = new ReentrantLock();  
02.    // 获取锁  
03.    lock.lock();  
04.    try {  
05.        // access the resource protected by this lock  
06.    } finally {  
07.        // 释放锁  
08.        lock.unlock();  
09.    }  

 

    void unlock(); ----执行此方法时,当前线程将释放持有的锁。锁只能由持有者释放,如果线程并不持有锁,却执行该方法,可能导致异常的发生。

    boolean tryLock(); ----如果锁可用, 则获取锁, 并立即返回true, 否则返回false. 该方法和lock()的 区别在于, tryLock()只是"试图"获取锁, 如果锁不可用, 不会导致当前线程被禁用, 当前线程仍然继续往下执行代码. 而lock()方法则是一定要获取到锁, 如果锁不可用, 就一直等待, 在未获得锁之前,当前线程并不继续向下执行.
通常采用如下的代码形式调用tryLock()方法:

01.   Lock lock = new ReentrantLock();  
02.   if (lock.tryLock()) {  
03.       try {  
04.           // manipulate protected state  
05.       } finally {  
06.           lock.unlock();  
07.       }  
08.   } else {  
09.       // perform alternative actions  
10.   }  

 Condition newCondition(); ----获得与该锁绑定的Condition对象,Condition后面再分析。

 void lockInterruptibly() throws InterruptedException; ----如果当前线程未被中断且可用,则获取锁并立即返回。 如果锁不可用,将禁用当前线程,并且在发生以下两种情况之一以前,该线程将一直处于休眠状态:

  • 锁由当前线程获得;或者
  • 其他某个线程中断当前线程,并且支持对锁获取的中断。

     

     

     

     

     

     

  • 抱歉!评论已关闭.