简体   繁体   English

具有不同类的同步块作为锁

[英]synchronized block with different class as lock

I want to know if my understanding of synchronized(x.class){..} is correct.我想知道我对synchronized(x.class){..}理解是否正确。

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.我只想明智地阻止变量而不是完整的 SingletonExample 实例。

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 .我的最终目标是,没有两个线程可以同时更改变量var ,也没有两个线程可以同时更改变量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 :更好的方法是使用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 ).如果var的当前值等于第一个参数(在本例中为null ),则这只设置var值。

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

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