Java 是否可以同步半个if块?

Java 是否可以同步半个if块?,java,multithreading,synchronization,Java,Multithreading,Synchronization,这个问题似乎很明显,但我还是不清楚 我有以下课程: public class MyClass{ private Object lock = new Object(); private boolean flag; public void method(){ //Start synchronization block if(!flag){ flag = true; //end synchroniza

这个问题似乎很明显,但我还是不清楚

我有以下课程:

public class MyClass{

    private Object lock = new Object();
    private boolean flag;


    public void method(){
        //Start synchronization block
        if(!flag){
            flag = true;
        //end synchronization block
            //do some bulk operation, should be synchronized
        }
        //some other staff
    }
}

问题是我不能把我需要同步的代码放进去,因为它是不正确的。如何进行这种同步?也许我可以利用java.util.concurrent中的一些东西。

您可以使用synchronized获取对象的监视器此{/*ToDo-synchronized code here*/}


或者,如果获取对象的监视器会导致并发问题,您可以在对象的一个字段上进行同步。

您可以使用Synchronized此{/*ToDo-Synchronized code here*/}获取对象的监视器


或者,如果获取对象的监视器会导致并发问题,则可以在对象的一个字段上进行同步。

通过这种方式,可以使用同步块:

synchronized(this)
{
    // synchronized block
}

通过这种方式,您可以使用同步块:

synchronized(this)
{
    // synchronized block
}

您也可以使用AtomicBoolean执行此操作,而无需显式同步:

public class MyClass{

    private AtomicBoolean flag = new AtomicBoolean(false);

    public void method(){
        if(flag.compareAndSet(false, true)) {
            //do some bulk operation, should be synchronized
        }
        //some other staff
    }
}
只有在之前没有任何内容进入块时,才会进入块,并且是线程安全的


当然,块中可能还有其他东西也需要同步。但是,这适用于所述的问题。

您也可以使用原子布尔值在不进行显式同步的情况下执行此操作:

public class MyClass{

    private AtomicBoolean flag = new AtomicBoolean(false);

    public void method(){
        if(flag.compareAndSet(false, true)) {
            //do some bulk operation, should be synchronized
        }
        //some other staff
    }
}
只有在之前没有任何内容进入块时,才会进入块,并且是线程安全的


当然,块中可能还有其他东西也需要同步。但是,这适用于所述的问题。

您的代码看起来像是AtomicBoolean的完美用例,它有一个方法compareAndSet,用于自动检查布尔值,并在检查返回预期值时设置它:

private AtomicBoolean flag = new AtomicBoolean();

public void method() {
    if (flag.compareAndSet(false, true)) {
        // ...
    }

    // other stuff
}

您的代码看起来像是AtomicBoolean的完美用例,它有一个方法compareAndSet,用于自动检查布尔值,并在检查返回预期值时设置它:

private AtomicBoolean flag = new AtomicBoolean();

public void method() {
    if (flag.compareAndSet(false, true)) {
        // ...
    }

    // other stuff
}
不要忘记java.util.concurrent.locks.Lock,它比java的内置锁定功能更强大,因此更危险。它允许您执行以下操作:

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

final Lock myLock = new ReentrantLock();

myLock.lock();
if (...) {
    ...
    myLock.unlock();
    ...
} else {
    myLock.unlock();
    ...
}
不要忘记java.util.concurrent.locks.Lock,它比java的内置锁定功能更强大,因此更危险。它允许您执行以下操作:

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

final Lock myLock = new ReentrantLock();

myLock.lock();
if (...) {
    ...
    myLock.unlock();
    ...
} else {
    myLock.unlock();
    ...
}

您可以阻止同步。@St.Antario的可能重复项为什么要同步一半?我认为不可能您可以阻止同步..可能重复@St.Antario为什么要同步一半?我认为删除我的答案是不可能的,因为有像你这样更好的解决方案;是的,这正是我想要的。删除我的答案,因为有更好的解决方案,像你的;是的,那正是我想要的。