如何在Java中有条件地禁用同步块?

时间:2014-12-12 17:12:54

标签: java multithreading locks

我可以这样做:

synchronized(isSynchronized ? myLock : null) {

}

我想通过标志禁用/启用同步。有可能吗?

5 个答案:

答案 0 :(得分:2)

您可以使用锁定(https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/Lock.html)并手动锁定。

if (shouldSync) {
  lock.lock();
}
try {
  // do your stuff
} finally { 
  if (shouldSync) {
    lock.unlock();
  }
}

答案 1 :(得分:1)

传递到synchronized块的参数不是语句,而是要同步的对象(互斥锁)。要以任何原因禁用同步,您应该将语句包含在if条件中:

if(condition){
    synchronized(myLock){
        // Critical segment
    }
}

但请注意,如果condition的评估可能依赖于多个线程(即从不同线程多次写入布尔值),则可能需要使用现有的线程安全机制,如AtomicBoolean这样:

AtomicBoolean condition = ... // defined elsewhere

if(condition.get()){
    synchronized(myLock){
        // Critical segment
    }
}

如果需要在同步方法上进行条件同步,请从方法声明中删除synchronized关键字并将其移动到正文中:

public synchronized void foo(){
    // Critical segment
}

public void foo(){
    if(condition){
        synchronized(this){
            // Critical segment
        }
    }
}

答案 2 :(得分:0)

不确定。事先使用if。另外,请确保变量isSynchronized标记为volatile

if (isSynchronized) {
  synchronized(myLock) {
    // ...
  }
}

当然,当isSynchronized为假时,不会同步。这并不是一个好主意,如果它是线程安全的,它就不应该同步。如果它不是线程安全的,它应该是同步的。

答案 3 :(得分:0)

您无法同步null。因此,如果您有另一个互斥锁,那么肯定可以执行以下操作:

synchronized(isSynchronized ? myLock : myLock2) {
}

否则你可以检查并输入关键部分,如:

if (isSynchronized) {
    synchronized(myLock) {..}
}

答案 4 :(得分:0)

对于初学者来说这是怎么回事:

if (isSynchronized) {
    synchronized(lock) { return doStuff(...); }
} else {
    return doStuff(...);
}

private MyType doStuff(...) {
    ...
}