首页 文章

锁定对象应该是volatile吗(synchronized块,多个类的实例)?

提问于
浏览
3

我已经从类A创建了三个对象 . 所有这三个对象都可以更新存储在类A中的私有静态volatile变量中的值 . 更新此变量是在具有特定条件的同步块中完成的 . 我想通过使用锁对象来同步块 .

首先,对象是在MainClass中创建的

A a1 = new A();
A a2 = new A();
A a3 = new A();

在此之后,物体开始过自己的生活 . 这是我的A类的简化示例 .

public class A{
    private static volatile String sharedVariable;
    Object lockObject = new Object();

    private void updateVariable(String newValue){
        //... some code
        synchronized(lockObject){
            //... code to check whether to update the value
            sharedVariable = newValue;
        }
    }

如果我希望synchronized块与所有实例和A类的所有线程同步,我应该将lockObject声明为私有静态volatile吗?如果我使用类(this)同步块,它会完成同样的事情吗?

我认为使用上面的代码,类A的所有实例都创建自己的lockObject并与之同步 . 因此,只有每个实例(a1,a2和a3)中的线程才会发生同步 . 它是否正确?

2 回答

  • 5

    volatile提供的是之前发生的保证,即所有线程中的后续读取将看到最近写入的值 .

    挥发性和静态的目的不在这里 .

    如果将锁定对象定义为实例变量,则将为 A 的每个实例创建它,这绝对不是必需的 .

    由于需要同步访问的对象是静态的,因此您需要创建一个 static final 锁定对象 . final (尽管没有必要,但是一个好的做法)确保锁定对象是可见的,并且在运行时不会更改,静态会使单个锁访问对象

    public class A{
        private static volatile String sharedVariable;
        private static final Object lockObject = new Object();
    
        private void updateVariable(String newValue){
            //... some code
            synchronized(lockObject){
                //... code to check whether to update the value
                sharedVariable = newValue;
            }
        }
    

    更多关于此:

  • 0

    对象级锁定不足以保护类变量 . 你需要 class 锁 .

    volatile 变量用于不同目的 . 当您在一个线程中更新变量的值并从多个线程中读取变量的值时,它非常有用 .

    看看下面的解决方案 .

    • 使用Gurwinder Singh提出的静态最终锁定

    • 使用 synchronized(A.class) 更新静态变量

    • 使用AtomicReference

    相关的SE问题:

    When to use AtomicReference in Java?

    Difference between volatile and synchronized in Java

相关问题