【问题标题】:Volatile and synchronized keywords in Java [duplicate]Java中的可变关键字和同步关键字[重复]
【发布时间】:2012-12-09 12:27:09
【问题描述】:

可能重复:
Difference between volatile and synchronized in JAVA (j2me)

我对@9​​87654323@ 和volatile 这两个java 关键字有点困惑。

据我了解,由于 java 是 multi-threaded 语言,并且使用关键字 synchronized 将强制它在 1 个线程中执行。我说的对吗?

volatile 也做同样的事情?

【问题讨论】:

  • "java 是一种多线程语言"。如果你的意思是 Java 是线程安全的,那不是真的。
  • 根据javarevisited.blogspot.com/2011/04/… 说它是一种多线程语言。
  • 该页面看起来一点也不可信。 Java 支持线程,我猜如果您在代码中启动多个线程,您就是在创建一个多线程应用程序。然而,Java 作为语言并没有非常新颖的结构来运行线程。

标签: java


【解决方案1】:

volatile 和 synchronized 都保证了可见性,但 synchronized 也提供了原子性:

  • 如果一个线程线程读取一个 volatile 变量,它可以保证看到之前对同一变量的写入,包括是否由其他线程完成
  • 同步块提供相同的保证(前提是写入和读取在同一个监视器上完成),但也提供原子性保证:同步块中的所有指令在同一个锁上同步的另一个线程看起来都是原子的。

【讨论】:

    【解决方案2】:

    Java 多线程涉及两个问题,确保可以一致地完成多个操作,而不会混合不同线程的操作,以及使变量值的更改对执行更改以外的线程可用。

    实际上,变量自然不会存在于硬件中的单个位置。不同线程的内部状态中可能存在副本,或者在不同的硬件缓存中。从执行分配的线程的角度来看,简单地分配给变量会自动更改其值。

    如果变量被标记为“volatile”,其他线程将获得更改后的值。

    “同步”还确保更改变得可见。具体来说,在同步块结束之前在一个线程中所做的任何更改对于在同一对象上同步的后续块中的另一个线程所做的读取都是可见的。

    此外,在同一个对象上同步的块被强制按顺序运行,而不是并行运行。这允许人们做一些事情,比如将一个变量加一,知道它的值在读取旧值和写入新值之间不会改变。它还允许对多个变量进行一致的更改。

    我知道了解用 Java 编写可靠的并发代码所需的最佳方法是阅读 Java Concurrency in Practice

    【讨论】:

      【解决方案3】:

      Volatile 关键字将使每个线程在内存位置中读取或写入作为原子操作。如果您不使用 volatile,则该变量可能会被线程缓存,并且线程可能正在读取/写入缓存副本而不是实际副本。

      【讨论】:

      • ad atomic operation in memory location 是什么意思?
      • 抱歉,打错了,我的意思是读取或写入变量将是原子操作。
      • volatile 的主要承诺不是关于原子性,而是关于可见性。
      • 嗯,我很多次都遇到了关于不在线程中使用 volatile 的问题,因为线程不共享共享布尔变量,他们正在访问缓存副本..
      【解决方案4】:

      同步意味着在给定时间只有一个线程可以访问方法或代码块。

      Volatile 处理线程之间的通信。这是一个很好的解释:http://jeremymanson.blogspot.be/2008/11/what-volatile-means-in-java.html

      【讨论】:

      • 谢谢。从您提供的链接中了解volatile
      【解决方案5】:

      就像Java Memory Model中描述的那样复杂。

      【讨论】:

        【解决方案6】:

        对于longdouble 的读写操作不是原子的。 volatile 是一个修饰符,您可以将其放在变量上以使读写操作原子化(包括longdouble

        文章Atomic Access得到了更多相关信息。

        基本上这是为了确保如果一个线程更改了变量的值,其余线程将看到该更改并且在写入时无法读取它。

        【讨论】:

        • 上面说volatile是用来减少内存一致性错误的?这是什么意思
        • @user1315906 线程可以缓存变量的值。因此,即使一个线程将更新某个值,其他线程也存在使用其缓存值的风险。为了防止缓存变量使用volatile
        • volatile 的主要承诺不是关于原子性,而是关于可见性。
        【解决方案7】:

        本质上,volatile是用来表示一个变量的值会被不同的线程修改。

        Synchronized 是一个关键字,其总体目的是一次只允许一个线程进入特定的代码部分,从而允许我们保护变量或数据不被来自不同线程的同时修改破坏。

        【讨论】:

        • 一个简单的谷歌搜索提供了很好的答案。
        猜你喜欢
        • 2022-12-19
        • 1970-01-01
        • 2021-10-26
        • 2011-01-17
        • 1970-01-01
        • 1970-01-01
        • 2011-12-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多