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

为什么要在Java中同步单个语句?

颛孙钱青
2023-03-14

我是一个学习如何在android上编码的模拟人,所以如果这个问题听起来很愚蠢,请容忍我。

我理解同步的要点。如果我有两个线程都可以访问和修改的数据,这可能会导致两个线程中数据变量的值不一致。

使方法同步并锁定它们直到一个线程执行完它(执行任何条件检查)是有意义的,但是为什么它与单个语句有关系呢?这对于多条语句来说很重要,因为在两条或更多条语句之间,线程一有可能会脱离可运行状态,但是我不明白一条语句有什么意义。

下面是一个示例

如果我有一个可以从游戏线程调用的监听器,它修改了一个数据变量,为什么我会这样做......

    public void onCompletionListener(MediaPlayer player){
    synchronized (this){
        isPrepared = false;
       }
    }

我还有另一种方法在我的音乐类称为停止

   public void stop(){
   mediaPlayer.stop()
    synchronized(this){
    isPrepared = false;
       }
    }

我为什么要费心这么做?这样做是为了两个线程之间的值的一致性吗?如果可以,我可以用volatile之类的吗?那会更好吗?

我这么问是因为我听说同步很贵。有更好的选择吗?

提前感谢大家回答我的问题。我很感激。编辑:我在一条语句中读到了这个同步?

我想我明白了……如果有人能详细说明的话,那就太棒了。此外,我最初提出的关于volatile是否是更好的选择的问题的第二部分也没有得到回答:)

共有3个答案

皮弘博
2023-03-14

作为对前面答案的补充,我想补充一点,例如,在某些情况下,您的单行源代码可以转换为多行机器可执行代码

柜台

尽管它看起来像一个操作,但表达式计数器实际上是三个单独的操作:

1)读取计数器的值

2)将该值加1

3) 将更新的值存储在计数器中

因此,这种语句也应该在多线程上下文中同步。

张鹏鹍
2023-03-14

在您的情况下,在布尔值上使用易失性也可以在不同步的情况下工作。
原始布尔值表示为4字节值,并将写入一个(汇编器)语句中。

这并不保证适用于8字节值(例如long / double ),其中一个线程可以写入低4字节,而另一个线程可以写入高4字节。

左丘昊天
2023-03-14

之所以这样做,是因为同步还对线程之间的内存可见性提出了要求。

如果该写入操作未同步或不稳定,则对于其他线程何时可见,没有任何硬性要求。另一个线程可能在其堆栈中有一个 isPrepared 的副本,上面写着 true,它可以永远运行,而不必知道返回主内存并检查其他人是否更改了,如果没有同步或易失性引用,则准备。

volatile关键字将满足确保其他线程看到更新的直接要求。在没有看到整个类/系统的情况下,很难说它是否是一个可接受的替代品。可能还有其他同步方法,当其中一个方法正在执行中时,更改isPrepared的状态是非法的。显然,为了支持易失性引用而移除同步是错误的。

 类似资料:
  • 问题内容: 我对Java真的很陌生,我读到Java 非常昂贵。我只想知道什么是昂贵的,它又如何昂贵? 谢谢。 问题答案: 也许还没有你想的那么糟 它曾经是可怕的(这可能就是您读到它“非常昂贵”的原因)。这些模因可能需要很长时间才能消失 由于涉及缓存刷新和失效的规则,因此Java语言中的同步块通常比许多平台提供的关键部分功能更为昂贵,而这些平台通常使用原子的“测试并设置位”机器指令来实现。即使程序仅

  • 问题内容: 在 Java 7中 ,对象可以位于语句的表达式中。有人可以从官方文档中解释以下声明吗? 与使用链式if-then-else语句相比,Java编译器通常从使用 String对象的 switch语句生成更有效的字节码。 问题答案: Java代码 具有一个类的两个版本,例如 与: 与: 字节码 让我们看一下字节码。获取版本的字节码: 获取版本的字节码: 结论 在第一个版本中,通过为每个条件调

  • 问题内容: 语句的用途是什么? 问题答案: 它是一种以互斥形式构建的Java。这用于多线程应用程序。 Sun并发教程 这部分有一个关于同步的部分,但是如果您尝试使用多线程应用程序,则应该阅读整个内容。 维基互斥

  • 问题内容: 我指的是此处提出的问题,并使用作者代码示例,现在我的问题是 作者为什么要使用,真的有必要吗,因为syncedMap始终会确保没有两个线程试图对其进行操作,那么为什么需要在该地图本身上进行操作呢? 非常感谢您的解释。 问题答案: 为什么我们需要对其本身进行同步? 您可能需要在一个已经同步的集合上进行同步,因为您正在对该集合执行两个操作-在您的示例中,是a 然后是a。您试图在 _调用_集合

  • 问题内容: 我一直在尝试学习设计模式。该网站使用关键字,但我不知道它的作用。 我在网上搜索后发现,它与多线程和内存有一定关系,但是我是机械工程师,不知道这意味着什么。 有人可以帮我理解线程和关键字吗? 问题答案: C ++中没有关键字。 但是,在Java中有一种方法对于方法来说意味着以下两件事: * 同一对象上的两个同步方法调用不可能交错。当一个线程正在为对象执行同步方法时,所有其他为同一对象块调

  • 问题内容: 我知道String [] args是作为参数传递给main的字符串数组。 但是,当您不将其包含为参数时(即使您不使用它),它也会引发异常。那么为什么需要它呢?另外,为什么不能是int []或boolean []? 问题答案: 这是一个字符串,因为命令行以文本形式表示。如果要将文本转换为整数或布尔值,则必须自己做- 操作系统或Java引导程序如何确切知道您希望如何解析所有内容?我想Jav