是可重入锁是完全替换同步?

时间:2016-10-10 14:50:01

标签: java multithreading synchronization locking

我浏览了文章“http://www.ibm.com/developerworks/java/library/j-jtp10264/”。他们提到“The Lock框架是同步的兼容替代品”。我理解通过使用Reentrant锁我们可以保持方法之间的锁,等待锁定一段时间(使用synchronized块(或)方法是不可能的)。我的疑问是,是否可以用具有重入锁的同步机制替换应用程序?

例如,我想实现一个线程安全堆栈数据结构,其中所有push,pop,getTop方法都是同步的,因此在多线程环境中,一次只能有一个线程能够访问一个同步方法(如果一个线程正在使用push方法,没有其他线程能够访问push,pop,getTop(或)Stack类的任何其他同步方法。是否可以使用Reentrant锁实现相同的线程安全堆栈数据结构?如果可能的话,请提供一个例子来理解这一点。

4 个答案:

答案 0 :(得分:3)

您可以使用synchronized执行的任何操作也可以使用ReentrantLock,但反之亦然。话虽如此,如果你需要的只是lock/unlock语义,我会建议synchronized,因为它在我看来更具可读性。

答案 1 :(得分:2)

答案是"是"。

使用

lock - unlock对代替synchronize( ) { ... }await中的signalCondition替换为waitnotify

答案 2 :(得分:0)

Brian Goetz在第13.4章的"Java Concurrency in Practice"中讨论了这个问题:

  对于内部锁定不实用的情况,

synchronized (lock) { // ... } 是一种高级工具。如果您需要其高级功能,请使用它:定时,轮询或可中断锁定获取,公平排队或非块结构锁定。否则,更喜欢同步。

我绝对同意,因为恕我直言:

try {
    lock.lock();
    // ...
} finally {
    lock.unlock();
}

比这更容易阅读,更不容易出错:

synchronized

长话短说:从技术角度来看,是的,您可以将ReentrantLock替换为services.AddTransient<ILogger>(provider => new Logger(Configuration["..."])) services.AddTransient<ICatalogService, CatalogService>(); ,但我本身不会这样做。

同时查看以下问题:

答案 3 :(得分:0)

ReentrantLock是同步的替代方案之一。

  

可重入互斥锁具有与使用同步方法和语句访问的隐式监视器锁相同的基本行为和语义,但具有扩展功能。

有关同步的其他替代方法(并发集合,原子变量,执行程序,ThreadLocal变量),请参阅此问题:

Avoid synchronized(this) in Java?