本文正在参加「Java主题月 – Java Debug笔记活动」,详情查看<活动链接>
提问:如果可以使用synchronized (this),那么使可重入锁如此重要的原因是什么?
我正在尝试了解,如果可以使用synchronized (this),那么使可重入锁如此重要的原因是什么。在以下代码中,我可以做到任一点:
1, 锁住一整个方法区或者一个代码块
2, 或者用可重入锁锁住一个代码块
private final ReentrantLock lock = new ReentrantLock();
private static List<Integer> ints;
public Integer getResult(String name) {
.
.
.
lock.lock();
try {
if (ints.size()==3) {
ints=null;
return -9;
}
for (int x=0; x<ints.size(); x++) {
System.out.println("["+name+"] "+x+"/"+ints.size()+". values >>>>"+ints.get(x));
}
} finally {
lock.unlock();
}
return random;
}
复制代码
与synchronized结构不同,ReentrantLock是非结构化的-即您不需要使用块结构进行锁定,甚至可以跨方法持有锁定。 一个例子:
private ReentrantLock lock;
public void foo() {
...
lock.lock();
...
}
public void bar() {
...
lock.unlock();
...
}
复制代码
这种流程是synchronized因结构所限做不到的。
除此之外,还ReentrantLock支持锁定轮询和支持超时的可中断锁定等待。ReentrantLock还支持可配置的公平性策略,从而允许更灵活的线程调度。
什么时候应该使用ReentrantLock?
答案很简单-在您确实需要它提供的东西时而synchronized又提供不了这些时使用ReentrantLock,例如定时锁等待,可中断锁等待,非块结构锁,多个条件变量或锁轮询。ReentrantLock它还具有可伸缩性的好处,如果您实际遇到竞争激烈的情况,则应使用它,但是请记住,绝大多数synchronized块几乎从未表现出任何竞争,更不用说竞争激烈了。我建议您使用synchronized进行开发,直到证明synchronized不够用为止,而不是简单地假设“性能会更好”(如果您使用ReentrantLock。请记住,这些是面向高级用户的高级工具。并且真正的高级用户倾向于确信可以找到的最简单的工具,直到他们确信简单的工具是不合适的。)和往常一样,首先使其正确,然后再担心是否必须使其更快。