一、
在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