如何在Java中有条件地锁定?

如何在Java中有条件地锁定?,java,locking,synchronized,Java,Locking,Synchronized,我一直在利用Java的synchronized块使我的部分代码线程安全。我正在向java移植一个数据结构,它通常可以使用synchronized块,但我并不总是知道如何以典型的java方式使用它们 以下是一个场景的示例: myMethod (Bool useLock) { if (useLock) { //locks the following section of code until unlocked. lockObject.l

我一直在利用Java的
synchronized
块使我的部分代码线程安全。我正在向java移植一个数据结构,它通常可以使用
synchronized
块,但我并不总是知道如何以典型的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中实现类似的功能?在这段代码中,有时我想锁定,有时我不想锁定,但我想聪明一点,不必编写同一代码的两个版本。除了使用
同步的
块,Java中还有其他锁定方法吗?

您可以使用不安全的方法来监视进入和监视退出,但这是一个坏主意

如果不需要锁,JVM几乎会在任何情况下优化它们
synchronized
在只有一个线程获得它时非常有效。(与锁不同,例如)

除了使用同步块,Java中还有其他锁定方法吗

是的-,尤其是
ReentrantLock
类,但是正如Peter所说,如果您可以不使用
synchronized
,那么总体来说它可能会更高效(并且更易于维护,特别是当您作为团队的一部分工作时)。

您可以使用锁对象,尤其应该使用锁对象

或者您仍然可以使用
同步的
块来解决问题。您问题中的代码如下所示:

myMethod (Bool useLock) {
    if (useLock) {
        synchronized (this) {
           criticalSection();
        }
    } else {
        criticalSection();
    }
}

criticalSection() {
   //do more stuff....
}
或者,如果要保证类的不同实例之间的互斥性,则应使用除此之外的其他监视对象。例如
classname.class
或该类的其他明确定义的静态变量。

我猜可以在您的场景中使用

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()
    }
  }
 }
您可以使用Java对象和对象
Condition
class'java文档也给出了一个非常好的
isFull
isEmpty
示例

在您的情况下,我想,您可以使用condition对象使代码更可读/更容易理解。大概是这样的:

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

并使用适当的条件

已经发布了一些不错的答案,但我想添加另一个适合我的解决方案:

我从以下几点开始:

...
synchronized(<lockobject>) {
 <huge section of code with lots of variables>
}
...
。。。
同步的(){
}
...
将其更改为:

...
synchronized(<condition> ? <lockobject> : new Object()) {
 <huge section of code with lots of variables>
}
...
。。。
已同步(?:新对象(){
}
...

基本上,如果条件为true,它将使用lockobject上的synchronized执行代码,但如果条件为false,它将使用“new Object()”,这基本上允许它在不进行任何同步的情况下运行。

他已经指定了要锁定的对象:
lockobject
。而且
Bool
不是标准的Java类。我最终使用了您的同步解决方案。我看了ReentrantLock的,谢谢!但它们似乎并不相互排斥同步块。