简体   繁体   中英

synchronized block with different class as lock

I want to know if my understanding of synchronized(x.class){..} is correct.

Assumption:

  1. I have two variables within a class which will be initialized, if needed. But only once.

  2. I want to block multiple access to each variable from different threads.

  3. I only want to block variable wise and not to the complete SingletonExample instance.

Example:

public class SingletonExample{

    private volatile SingletonA var;
    private volatile SingletonB tar;

    public void initVarOnDemand1() {
        if (var == null) {
            synchronized (SingletonA.class) {
                if (var == null) {
                    var = SingletonA.getInstance(1);
                }
            }
        }
    }

    public void initVarOnDemand2() {
        if (var == null) {
            synchronized (SingletonA.class) {
                if (var == null) {
                    var = SingletonA.getInstance(2);
                }
            }
        }
    }

    public void initTarOnDemand1() {
        if (tar == null) {
            synchronized (SingletonB.class) {
                if (tar == null) {
                    tar = new SingletonB.getInstance(1);
                }
            }
        }
    }

    public void initTarOnDemand2() {
        if (tar == null) {
            synchronized (SingletonB.class) {
                if (tar == null) {
                    tar = SingletonB.getInstance(2);
                }
            }
        }
    }
}

My final goal is, that no two threads can simultaneously change variable var and no two threads can change simultaneously variable tar .

But I do not want to block two threads, that access different variables.

Therefore I use block synchronization with each class as the lock object.

Is this the correct way for what I want? (I hope I explained it well enough - sorry for my bad english).

A better approach to this would be to use AtomicReference.compareAndSet :

private final AtomicReference<Integer> var = new AtomicReference<>();

public void foo() {
  var.compareAndSet(null, 1);
}

public void bar() {
  var.compareAndSet(null, -1);
}

This only sets the value of var if its current value is equal to the first parameter (in this case null ).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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