当前位置: 首页 > 知识库问答 >
问题:

锁对象是否应该是易失性的(同步块、类的多个实例)?

姬锐
2023-03-14

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

因此,首先在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;
        }
    }

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

我认为使用上面的代码,类A的所有实例都创建了自己的lockObject并与之同步。因此,同步只会发生在每个实例(a1、a2和a3)中的线程上。这样做正确吗?

共有2个答案

毋玺
2023-03-14

对象级锁不足以保护类变量。你需要类级锁。

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

看看下面的解决方案。

  1. 使用Gurvinder Singh建议的静态最终锁

相关SE问题:

何时在Java中使用原子参考?

Java中volatile和synchronized的区别

钮边浩
2023-03-14

volatile提供的是一个before保证,所有线程中的后续读取将看到最近写入的值。

挥发性和静态的目的在这里不混合。

如果您将lock对象定义为一个实例变量,那么它将为A的每个实例创建,这肯定是不需要的。

由于需要同步访问的对象是静态的,因此需要创建静态最终锁定对象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;
        }
    }

更多关于这个:

  • 同步块中的静态与非静态锁定对象
  • 如果我在实例方法中放置静态锁,会发生什么?
 类似资料:
  • 问题内容: 我正在建模一个游戏,其中多个玩家(线程)同时移动。玩家当前所在位置的信息被存储两次:该玩家具有一个变量“ hostField”,该变量引用板上的一个字段,每个字段都有一个ArrayList,用于存储当前位于该字段的玩家。 我对拥有冗余信息的事实不是很满意,但是我发现如果不遍历大数据集就无法避免这种情况。 但是,当玩家从一个字段移到另一个字段时,我想确保(1)冗余信息保持链接(2)此刻没

  • 在示例代码中 在这个页面上, lock1和lock2分别控制c1和c2上的更新。 然而, 正在获取对象lock1的锁并在同步块时释放它 被执行。 当这个代码块被执行时,这个对象的成员c1上可能还有一个更新——我看不出这个更新是如何被代码中的lock1上的同步所阻止的。 只有对象lock1可以独占访问——除此之外别无它物(?) 那么,实施情况如何 在上面的代码中不同于 甚至 当c1是一个对象而不是一

  • 我有多个线程使用ElasticSearchClient,如下所述 据我所知,Singleton类是线程安全的,但我不确定如果多个线程开始执行Singleton类的同一方法会发生什么。这有副作用吗? 注意:我知道上面的singleton类不是反射和序列化安全的。

  • 问题内容: 我正在编写一个JavaScript函数,该函数发出HTTP请求并返回对结果的承诺(但该问题同样适用于基于回调的实现)。 如果我立即知道为该函数提供的参数无效,该函数应该同步还是应该返回被拒绝的Promise(或者,如果您愿意,请使用实例调用回调)? 异步功能应 始终 以异步方式运行(特别是对于错误情况)有多重要?是否确定,如果你知道程序是不是一个合适的状态的异步操作继续进行? 例如:

  • 对于此示例: 如何检查 是否是 Foo 的实例(但不是其 foo 子类的实例)?那是: checkInstance(qux,Foo.class)=true checkInstance(qux,Bar.class)=false 有没有类似于< code>instanceof的语句来进行这种检查?或者我应该使用< code>qux.getClass()。equals(Foo.class)

  • 问题内容: 输出是 线程1开始 线程1的内部演示 线程2开始 线程2的内部演示 由于,执行尚未结束。 我已经通过类的同一个实例来的两个类的构造函数和。 对in 的调用位于一个块中。 要在通话中是 没有 的块。 所以,当被执行时,由于块,的监视器应锁定,导致拒绝访问,以由所述。 但是,这没有发生。 预期的输出是 (输出在完成之前。) 因此,我的基本问题是: 即使 尚未完成 块, 如何成功执行? 问题