Java并发原理学习笔记+总结+实战(5)——Lock接口

一、

    在JDK1.5之后,在java.util.concurrent.locks的包中提供了另一种实现代码同步的方法,Lock。

    在前面说过,synchronize锁是一种重量级的,特别耗费资源的锁。在使用synchronize中,当线程被阻塞或等待处理,但又没有释放锁时,其他线程只能在外面等待,非常影响执行效率。这就需要有一种机制可以不让等待的线程一直无期限地等待下去(比如只等待一定的时间或者能够响应中断),通过Lock就可以办到。

    但是需要注意:

    1)Lock需要显示地获取和释放锁,繁琐能让代码更灵活

    2)Synchronized不需要显示地获取和释放锁,简单

二、

查看Lock的源码可以看到,Lock接口主要有这几个方法:

                              

其中,lock()、lockInterruptibly()、tryLock()和tryLock(long time, TimeUnit unit)是用来获取锁的,unlock()是用来释放锁的。

2.1 lock()

    lock()方式是最常用的获取锁的方法。如果当时锁不可用(被其他线程占用)则线程等待。由于lock是不会主动释放锁的,为了防止出现死锁的情况发生,lock()代码块必须进行异常捕捉与处理,并在finally中调用unlock()方法来保证锁的释放。

  private int value;
  Lock lock = new ReentrantLock();
  public int getNext() {
    lock.lock();
    int a = 0;
    try {
      a = value++;
    } catch (Exception e) {
      e.printStackTrace();
    }finally {
      lock.unlock();
    }
    return a;
  }

2.2 lockInterruptibly()

    当通过该方法获取锁时,如果锁可用,则获取锁;如果锁不可用,则当前线程进入等待(休眠)状态,直到发生以下情况:

     1)、对该等待线程调用interrupt()方法,中断该线程等待状态

     2)、如果当前线程在进入该方法前就调用interrupt()方法,即被设置为中断状态,或者在获取锁定时被中断,则会抛出InterruptedException异常,然后清除中断状态。

注意:当线程成功获取到锁之后是无法调用interrupt()方法中断的。因为interrupt()方法只能中断被阻塞过程中的线程。

2.3 tryLock()

    tryLock()方法是一个返回布尔值的方法,表示在能成功获取到锁时返回true;不能获取到锁返回false。该方法在无论能否成功获取到锁时都会及时的返回,而不会在不能获取到锁时等待。

Lock lock = ...;
if (lock.tryLock()) {
   try {
    // manipulate protected state
  } finally {
    lock.unlock();
  }
 } else {
  // perform alternative actions
 }
}

2.4 tryLock(long time, TimeUnit unit)

    tryLock(long time, TimeUnit unit)和tryLock()类似,只是多了两个参数:

    ·time : 最长等待解锁时间

    ·unit  : 时间单位

    该方法在调用时需要传递等待时间和单位,在等待时间内无法获取到锁则返回false,否则则返回true

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章