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

如何在Java中有条件地禁用同步块?,java,multithreading,locks,Java,Multithreading,Locks,我可以这样做吗: synchronized(isSynchronized ? myLock : null) { } 我想通过标志禁用/启用同步。可能吗?当然可以。如果,请在手前使用。另外,确保变量已同步已标记 当然,如果isSynchronized为false,则不会同步该值。这听起来不是个好主意,如果它是线程安全的,就不应该同步。如果它不是线程安全的,那么应该同步它。当然。如果,请在手前使用。另外,确保变量已同步已标记 当然,如果isSynchronized为false,则不会同步该值。这

我可以这样做吗:

synchronized(isSynchronized ? myLock : null) {

}

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

当然可以。如果,请在手前使用
。另外,确保变量
已同步
已标记


当然,如果
isSynchronized
为false,则不会同步该值。这听起来不是个好主意,如果它是线程安全的,就不应该同步。如果它不是线程安全的,那么应该同步它。

当然。如果
,请在手前使用
。另外,确保变量
已同步
已标记

当然,如果
isSynchronized
为false,则不会同步该值。这听起来不是个好主意,如果它是线程安全的,就不应该同步。如果它不是线程安全的,则应该同步。

您可以使用锁()并手动锁定它

if (shouldSync) {
  lock.lock();
}
try {
  // do your stuff
} finally { 
  if (shouldSync) {
    lock.unlock();
  }
}
您可以使用锁()并手动锁定它

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

您不能同步null的值。因此,如果您有另一个互斥体,那么您肯定可以执行以下操作:

synchronized(isSynchronized ? myLock : myLock2) {
}
否则,您可以检查并进入关键部分,如:

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

您不能同步null的值。因此,如果您有另一个互斥体,那么您肯定可以执行以下操作:

synchronized(isSynchronized ? myLock : myLock2) {
}
否则,您可以检查并进入关键部分,如:

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

对于初学者来说,这个怎么样:

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

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

对于初学者来说,这个怎么样:

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

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

传递到
synchronized
块的参数不是语句,而是要同步的对象(互斥体)。要出于任何原因禁用同步,应将语句封装在if条件中:

if(condition){
    synchronized(myLock){
        // Critical segment
    }
}
但是,请注意,如果对
条件的计算可能依赖于多个线程(即从不同线程多次写入布尔值),则可能需要使用现有的线程安全机制,如
AtomicBoolean

AtomicBoolean condition = ... // defined elsewhere

if(condition.get()){
    synchronized(myLock){
        // Critical segment
    }
}
如果需要对同步方法进行条件同步,请从方法声明中删除synchronized关键字并将其移动到正文中:

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


传递到
synchronized
块的参数不是语句,而是要同步的对象(互斥体)。要出于任何原因禁用同步,应将语句封装在if条件中:

if(condition){
    synchronized(myLock){
        // Critical segment
    }
}
但是,请注意,如果对
条件的计算可能依赖于多个线程(即从不同线程多次写入布尔值),则可能需要使用现有的线程安全机制,如
AtomicBoolean

AtomicBoolean condition = ... // defined elsewhere

if(condition.get()){
    synchronized(myLock){
        // Critical segment
    }
}
如果需要对同步方法进行条件同步,请从方法声明中删除synchronized关键字并将其移动到正文中:

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


不,不是。给我们更大的图景。你为什么要这样做?不,不是。给我们更大的图景。为什么要这样做?没有锁上释放这样的方法。还有,如果在OP的东西抛出异常呢?并没有锁上释放这样的方法。如果in-OP的stuff抛出异常呢?这种方法的问题是我必须将我的同步块作为一种方法。这有什么逃避吗?所以在这种情况下,您需要类似于
if(isSynchronized){mymethod();}
的东西,并确保您的isSynchronized变量是易变的。这种方法的问题是我必须将我的同步块设置为一个方法。那么在这种情况下,您需要类似于
if(isSynchronized){mymethod();}
的东西,并确保isSynchronized变量是可变的。