锁定API同步的优点

Adi*_*tya 3 java multithreading

每个博客或解释我都看到了Locks API优于同步的优点.

我想知道有什么优势的同步锁定,或任何我应该更喜欢同步而不是锁定的情况.

She*_*ard 7

你的意思是synchronized语句和方法关键字?隐式锁定的主要优点是需要更少的代码并在离开其范围时自动解锁.对于简单的锁定/等待操作,它是完美的解决方案.

所以下面的代码

public void myMethod() {
    synchronized(this) {
       // concurrent stuff
    }
}
Run Code Online (Sandbox Code Playgroud)

完全等同于

final private Lock lock = new ReentrantLock();

public void myMethod() {
    lock.lock();
    try {
        // concurrent stuff
    }
    finally {
        lock.unlock();
    }
}
Run Code Online (Sandbox Code Playgroud)

synchronized public void myMethod() {
    // concurrent stuff
}
Run Code Online (Sandbox Code Playgroud)

您还可以使用不同的对象进行同步(它们不受任何影响,仅作为控制点):

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
     }
}
Run Code Online (Sandbox Code Playgroud)


Ste*_*n C 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 {
       ...
    }
}
Run Code Online (Sandbox Code Playgroud)

第一个可能会出现在测试中,但后两个可能不会.

你不能犯这些错误synchronized.


但是,Lock尽管有以下考虑因素,

  • 锁允许您实现不同的锁定策略,例如非重入锁定和多读取器/单写入器锁定.

  • 锁允许您跨范围/块结构边界保持锁定.(这使得您的代码更难以推理,但对于某些用例来说这是必要的;例如,需要跨多个事件处理程序保存锁的基于事件的设计.)

  • Lock API允许您测试锁定,获取锁定而不会阻塞,或者使用超时,并定义Condition对象.