简体   繁体   English

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

[英]How to conditionally disable a synchronized block in Java?

Can I do something like that: 我可以这样做吗?

synchronized(isSynchronized ? myLock : null) {

}

I want to disable/enable synchronization through a flag. 我想通过标志禁用/启用同步。 Is it possible? 可能吗?

You could use a lock ( https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/Lock.html ) and lock it manually. 您可以使用锁定( 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();
  }
}

The parameter passed into the synchronized block is not a statement but rather a object to synchronize upon (the mutex). 传递到synchronized块中的参数不是语句,而是要同步的对象(互斥体)。 To disable synchronization for whatever reason you should encase the statement in a if-condition as such: 要出于任何原因禁用同步,都应将语句放在if条件中,如下所示:

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

note however, if the evaluation of condition can be dependent on several threads (ie multiple writes to a boolean from different threads) you may need to use an existing thread-safe mechanism like AtomicBoolean as such: 但是请注意,如果condition的评估可能取决于多个线程(即,从不同线程多次写AtomicBoolean值),则可能需要使用现有的线程安全机制,例如AtomicBoolean ,例如:

AtomicBoolean condition = ... // defined elsewhere

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

if you need conditional synchronization upon a synchronized method, remove the synchronized keyword from the method declaration and move it into the body: 如果您需要在同步方法上进行条件同步,请从方法声明中删除synced关键字,并将其移至主体中:

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

to

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

Sure. 当然。 Use an if before hand. 先使用if Also, make sure the variable isSynchronized is marked volatile . 同样,确保变量isSynchronized标记为volatile

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

of course, that won't be synchronized when isSynchronized is false. 当然,如果isSynchronized为false,则不会同步。 And that doesn't sound like a great idea, if it's thread-safe it shouldn't be synchronized. 这听起来不是一个好主意,如果它是线程安全的,则不应同步。 If it isn't thread safe, it should be synchronized. 如果不是线程安全的,则应进行同步。

You can't synchronize of null. 您无法同步null。 So if you have another mutex, then definately you could do something like: 因此,如果您有另一个互斥锁,则可以确定地执行以下操作:

synchronized(isSynchronized ? myLock : myLock2) {
}

else you could check and enter the critical section like: 否则,您可以检查并输入关键部分,例如:

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

How about this for starters: 对于初学者来说怎么样:

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM