我如何有条件地锁定Java?
我一直在利用Java的synchronized
块来使我的代码线程部分安全。 我正在将数据结构移植到通常可以使用synchronized
块的java,但我并不总是知道如何以典型的Java方式使用它们。
以下是一个场景的示例:
myMethod (Bool useLock) { if (useLock) { //locks the following section of code until unlocked. lockObject.lock(); } //do more stuff.... if (useLock) { //unlocks exclusive control of code. lockObject.unlock(); } }
我如何在Java中完成相同的操作? 在这段代码中,有时我想锁定,有时我不想,但我想要聪明一点,而不必编写相同代码的两个版本。 除了使用synchronized
块之外,还有其他方法可以锁定Java吗?
你可以使用Lock对象,特别是ReentrantLock应该做的工作。 http://docs.oracle.com/javase/tutorial/essential/concurrency/newlocks.html
或者您仍然可以使用synchronized
块解决问题。 您问题的代码如下所示:
myMethod (Bool useLock) { if (useLock) { synchronized (this) { criticalSection(); } } else { criticalSection(); } } criticalSection() { //do more stuff.... }
或者,如果您希望保证类的不同实例之间的互斥,则应使用除此之外的其他监视器对象。 例如, TheClassName.class
或TheClassName.class
其他显式定义的静态变量。
我猜可以在您的场景中使用ReentrantLock
final Lock lock = new ReentrantLock();
示例代码段
class X { private final ReentrantLock lock = new ReentrantLock(); // ... public void m() { lock.lock(); // block until condition holds try { // ... method body } finally { lock.unlock() } } }
已发布一些好的答案,但我想添加另一个对我有用的解决方案:
我开始时:
... synchronized() { } ...
将其更改为:
... synchronized( ? : new Object()) { } ...
基本上,如果条件为真,它使用lock对象执行代码,但如果条件为false,则使用“new Object()”,它基本上允许它在没有任何同步的情况下运行。
你可以使用Unsafe来监控输入和monitorExit,但这是一个坏主意恕我直言。
如果不需要锁,JVM几乎可以在任何情况下优化它们。 如果只有一个线程获得它,则synchronized
非常有效。 (与Lock不同)
除了使用synchronized块之外,还有其他方法可以锁定Java吗?
是的 – java.util.concurrent.locks ,特别是ReentrantLock
类,但正如彼得所说,如果你可以通过使用synchronized
来逃脱它可能会更有效率(并且更容易维护,特别是如果你正在工作作为团队的一部分)。
您可以使用Java 锁定对象和Condition对象。 Condition
类’java docs也提供了一个非常好的isFull
和isEmpty
示例。
在您的情况下,我猜,您可以利用条件对象使代码更易读/可理解。 像这样的东西:
final Lock lock = new ReentrantLock(); final Condition useLock = lock.newCondition();
并酌情使用该条件。