可重入锁ReentrantLock
今天学习一下可重入锁ReentrantLock:
先来借别人的例子来看它怎么用:
这是java DelayQueue的take方法:
public E take() throws InterruptedException { final ReentrantLock lock = this.lock; lock.lockInterruptibly(); try { for (;;) { E first = q.peek(); if (first == null) { available.await(); //此时已经释放锁了,因为是等待状态,也不存在同步问题
//到这一步又获得了锁,可能是被signalAll方法唤醒的 } else { long delay = first.getDelay(TimeUnit.NANOSECONDS); if (delay > 0) { long tl = available.awaitNanos(delay);//释放锁到一定时间
//再次获得锁 } else { E x = q.poll(); assert x != null; if (q.size() != 0) available.signalAll(); //唤醒 return x; } } } } finally { lock.unlock(); } }
这是offer方法:
public boolean offer(E e) { final ReentrantLock lock = this.lock; lock.lock(); try { E first = q.peek(); q.offer(e); if (first == null || e.compareTo(first) < 0) available.signalAll();
//这里判断之前是空的,现在有元素了,应该唤醒,但是此时此方法还在保持锁
return true;
} finally {
lock.unlock();
}
}
参见:http://tenyears.iteye.com/blog/48750
详见java.concurrency.in.practice一书第十三章