并发-显式锁


Lock与ReentrantLock

  1. Lock接口

    • Lock提供了一种无条件的丶可轮询的丶可定时的以及可中断的锁获取操作,所有加锁和解锁的方法都是显式的
      public interface Lock{
        void lock(); //阻塞的获取锁,知道获取到锁才返回且不可中断
        void lockInterruptibly();//可中断的获取锁,在阻塞等待过程中可响应中断
        boolean tryLock();//尝试非阻塞的获取锁,调用方法后立即返回,获取锁成功返回true,失败返回false
        boolean tryLock(long timeout,TimeUnit unit);//限定了一个尝试获取锁的时间,在该时间内会尝试获取锁(成功true,失败false),超出时间后直接返回false
        void unlock();//释放锁
        Condition newCondition();//Condition对象:维护一个条件队列,await() singal()方法可以对其进行操作
      }
  2. ReentrantLock类

    • ReentrantLock类实现了Lock接口,并提供了与synchronized相同的互斥性和内存可见性,还提供了可重入的加锁语义,提供了更高的灵活性
      //Lock接口的标准使用形式
      Lock lock = new ReentrantLock();
      //...
      lock.lock();//获取锁
      try{
        //处理
      } finally{
        lock.unlock();//释放锁一定要在finally块中
      }
  3. 轮询锁与定时锁

    • 可定时的与可轮询的锁获取模式是由tryLock方法实现的,可以避免死锁的发生
      //通过tryLock来避免锁顺序死锁(非阻塞避免死锁)
      try{
        if(fromAcct.lock.tryLock()){ //尝试获取锁,直接返回结果,非阻塞(true,false)
            try{
                if(toAcct.lock.tryLock()){//尝试获取锁,直接返回结果,非阻塞
                    //其他
                }
            } finally{
                toAcct.lock.unlock();
            }
        }
      } finally{
        fromAcct.lock.unlock();
      }
      //带有时间限制的加锁(在timeout时间内没有获取到锁就返回false)
      if(!lock.tryLock(timeout,unit)) 
        return false;
      try{
        //获取锁成功时操作
        return doSomething();
      } finally{
        lock.unlock();
      }
  4. 可中断的获取锁操作

     //可中断的锁获取操作
     public boolean sendOnSharedLine(String message) throws InterruptedException{//中断会抛出InterruptedException异常
         lock.lockInterruptibly();   //可中断的获取锁
         try{
             return cancellableSendOnShareLine(message);
         } finally{
             lock.unlock();
         }
     }
  5. 公平锁与非公平锁

    • ReentrantLock构造函数中提供了两种公平性选择: 创建一个非公平锁(默认)或一个公平锁
    • 公平锁上,线程将按照他们发出请求的顺序来获取锁,非公平锁则允许插队
  6. synchronized与ReentrantLock之间的选择

    • 在一些内置锁无法满足需求的情况下,ReentrantLock可以作为一种高级工具,当需要一些高级功能时才应该使用ReentrantLock,这些功能包括: 可定时的丶可轮询丶与可中断的锁获取操作,公平队列,以及非块结构的锁,否则还是应该优先使用synchronized
  7. 读写锁

     public interface ReadWriteLock{
         Lock readLock();    //获取读锁
         Lock writeLock();   //获取写锁
     }
    • 读写锁加锁策略中,允许多个读操作同时进行,但是每次只允许一个写操作

文章作者: Bryson
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Bryson !
评论
 上一篇
并发-构建自定义的同步工具 并发-构建自定义的同步工具
构建自定义的同步工具 现有类库不能提供足够的功能时,可以使用内置的条件队列丶显示的Condition对象或者AbstractQueuedSynchronizer来构建自己的同步器 内置的条件队列 条件队列是指一组在等待某个条件变成真的线程
2019-09-02
下一篇 
并发-性能与可伸缩性 并发-性能与可伸缩性
影响性能的因素 性能与可伸缩性 可伸缩性指的是: 当增加计算资源时(如CPU丶内存丶存储容量或I/O带宽),程序的吞吐量或处理能力相应地增加 线程引入的开销 在多线程的调度和协调过程中都需要一定的性能开销: 对于为了提升性能而引入的
2019-08-28
  目录