每个博客或解释我都看到了Locks API优于同步的优势。
我想知道同步锁定有什么优势,或者我更喜欢同步而不是锁定的任何情况。
答案 0 :(得分:7)
你的意思是synchronized语句和方法关键字?隐式锁定的主要优点是需要更少的代码并在离开其范围时自动解锁。对于简单的锁定/等待操作,它是完美的解决方案。
以下代码
public void myMethod() {
synchronized(this) {
// concurrent stuff
}
}
完全等同于
final private Lock lock = new ReentrantLock();
public void myMethod() {
lock.lock();
try {
// concurrent stuff
}
finally {
lock.unlock();
}
}
和
synchronized public void myMethod() {
// concurrent stuff
}
您还可以使用不同的对象进行同步(它们不受任何影响,仅作为控制点):
final static private Object sync = new Object();
public void method1() {
synchronized(sync) {
// concurrent code involving static members
}
}
public void method2() {
synchronized(this) {
// concurrent code affecting this instance
}
}
答案 1 :(得分:6)
除了@ Shepard的答案之外,使用synchronized
不易出错。考虑一下可能导致锁定未被释放的错误:
final private Lock lock = new ReentrantLock();
public void myMethod() {
lock.lock();
// concurrent stuff
}
public void myMethod2() {
lock.lock();
// concurrent stuff that might throw an unchecked exception
lock.unlock();
}
public void myMethod3() {
lock.lock();
try {
// concurrent stuff
lock.unlock();
} catch ( ... ) {
...
} finally {
...
}
}
第一个可能会出现在测试中,但后两个可能不会。
您不能使用synchronized
犯下任何错误。
但是,尽管有以下考虑因素,Lock
仍然有用:
锁定允许您实现不同的锁定策略,例如非重入锁定和多读取器/单写入器锁定。
锁定允许您跨范围/块结构边界保持锁定。 (这使得您的代码更难以推理,但对于某些用例来说是必要的;例如,需要跨多个事件处理程序保存锁定的基于事件的设计。)
Lock API允许您测试锁定,获取锁定而不会阻塞或超时,并定义Condition
个对象。