当前位置: 首页 > 面试题库 >

使用volatile而不同步

漆雕宏浚
2023-03-14
问题内容

知道

对于声明为volatile的所有变量,读写是原子的

问题1: 这是否可以理解为

private volatile int x = 0;

x++; 操作是原子的吗?

然后

将变量标记为volatile并不能消除所有同步原子操作的需要,因为仍然可能发生内存一致性错误。

问题2:
我想知道在什么情况下(如果有的话)有可能看到一个已标记的变量volatile,而看不到任何标记为已同步的块的方法(试图访问/修改该变量)?

换句话说,是否需要标记所有需要防止并发修改的变量volatile


问题答案:

volatile仅为您提供其他可见性保证,多头/双数的原子写/读(否则JLS不保证,是的)和某些内存顺序保证。 没有
同步(虽然可以从volatile开始构建同步块-Dekker的算法),所以不,它无济于事x++-仍然是读取,写入和写入,并且需要某种形式的同步。

volatile的一个例子是著名的双重检查锁定,在这种情况下,大多数时候我们避免同步,因为排序保证就是我们所需要的:

private volatile Helper helper = null;
public Helper getHelper() {
    if (helper == null) {
        synchronized(this) {
            if (helper == null) {
                helper = new Helper();
            }
        }
    }
    return helper;
}

一个完全不涉及同步的示例是一个简单的退出标志,此处与订购保证无关,而仅与保证可见性有关

public volatile boolean exit = false;
public void run() {
   while (!exit) doStuff();
   // exit when exit set to true
}

如果另一个线程设置exit = true了另一个线程,则可以确保执行while循环时看到更新-如果没有volatile,则可能不会。



 类似资料:
  • 问题内容: 我有一个基于Seam 2.2的Java EE 5 Web应用程序,其中有一堆表通过Hibernate 3.3.3映射到JPA 1.0实体。在开发过程中,它在Tomcat 6,Oracle 10 XE和Windows 7上运行。 现在,运营部门提出了将数据模型拆分为一个模式(该模式是所有数据库对象的所有者)和一个充当应用程序的数据库用户的模式的请求。所以我做了以下事情: 创建模式 授予对

  • 问题内容: 我已经看过SO中的其他volatile与Atomicxxxx问题(包括此问题),并阅读了java.util.current.atomic的描述,但我对细微差别并不满意。 如果我要决定在和之间使用,除了AtomicBoolean提供的原子读取-修改-写入操作之外,还有其他实际区别吗?(例如和) 假设我有 然后,一个或多个线程设置该标志(但不清除它)。如果我有一个线程读取该标志,并且设置了

  • 问题内容: 有谁能举例说明同步方法优于同步块的优势吗? 问题答案: 在块上使用同步方法没有明显的优势。 也许唯一的一个(但我不会称其为优势)是你不需要包括对象引用。 方法: 块: 看到?完全没有优势。 但是,块确实比方法具有优势,主要是在灵活性方面,因为你可以将另一个对象用作锁,而同步该方法将锁定整个对象。 比较: 与 同样,如果方法变大,你仍然可以将同步部分分开:

  • 问题内容: 由多个线程访问但仅在同步块内部访问的变量是否需要volatile修饰符?如果没有,为什么? 问题答案: 您不需要在内部使用,synced已经保证了一致地使用(每次访问)时变量的本地缓存的正确行为。 适用于原始值,并且可以作为原子访问原始类型的理想捷径。请注意,在JDK 5中,volatile的行为已从1.4开始更改。 更多信息可以在这里找到

  • 在我的场景中,我必须将数据从一个web应用程序发送到一个有效的数据存储区webapi。请求必须是同步的,如果出现问题,我非常希望抛出,因为这意味着应用程序的关键部分不可用。 这是一个现有问题的衍生,但不是重复;为什么使用HttpClient进行同步连接? 但在我的场景中,我确实想要那种行为。虽然有很多很好的用例,但有人能给出在我的场景中不使用的好理由吗?我使用的对象是否正确?更重要的是,为什么?

  • 正是标题所说的。有没有办法在不安装TCL的情况下使用matplotlib库?请不要告诉我咬紧牙关安装TCL——我知道怎么做,但出于我自己(好吧,也许很愚蠢)的原因,我不想这么做。 我不关心显示的图,我只希望能够输出他们在png。我尝试了各种各样的东西(使用不同的后端等),但是matplotlib总是想找到tcl来工作:(为什么TCL对matplotlib如此重要? 此外,请注意,我正在使用wind