ReentrantLock
重入锁使用java.util.concurrent.locks.ReentrantLock类来实现。它的几个重要方法如下:
lock():获得锁,如果锁已经被占用,则等待。
lockInterruptibly():获得锁,但优先响应中断。
tryLock():尝试获得锁,如果成功,返回true,失败返回false。该方法不等待,立即返回。
tryLock(long time, TimeUnit unit):在给定时间内尝试获得锁。 unLock():释放锁。
对于重入锁,同一个线程可以多次获得锁,但是释放锁的时候,也必须释放相同次数。否则会产生异常。
Condition条件
通过Condition的newCondition()方法可以生成一个与当前重入锁绑定的Condition实例。利用Condition对象,我们就可以让线程在合适的时间等待,或者在某一个特定的时间得到通知,继续执行。
await() 方法会是当前线程等待,同时释放当前锁,当其他线程中使用signal() 或signalAll() 方法时,线程会重新获得锁并继续执行。或者当线程被中断时,也能跳出等待;signal() 方法用于唤醒一个在等待中的线程。
当线程使用Condition.await时,要求线程持有相关的重入锁,在Condition.await调用后,这个线程会释放这把锁。同理,在Condition.signal方法调用时,也要求线程先获得相关的锁。在signal方法调用后,系统会从当前Condition对象的等待队列中,唤醒一个线程。一旦线程被唤醒,它会重新尝试获得与之绑定的重入锁,一旦成功获取,就可以继续执行了。因此,在signal方法调用之后,一般需要释放相关的锁,谦让给被唤醒的线程,让他可以继续执行。
private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
public void method1(){
try {
lock.lock();
//释放锁,类似于 Object wait,阻塞于此
condition.await();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void method2(){
try {
lock.lock();
//不释放锁类,似于Object notify
condition.signal();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
网友评论