我如何有条件地锁定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.classTheClassName.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也提供了一个非常好的isFullisEmpty示例。

在您的情况下,我猜,您可以利用条件对象使代码更易读/可理解。 像这样的东西:

  final Lock lock = new ReentrantLock(); final Condition useLock = lock.newCondition(); 

并酌情使用该条件。