gpt4 book ai didi

java - 为什么 volatile 加上 synchronized 不起作用?

转载 作者:行者123 更新时间:2023-12-04 03:24:28 25 4
gpt4 key购买 nike

我正在尝试了解 Java 中的并发性。我知道同步,它在对象上创建一个监视器,之后另一个线程无法对该对象进行操作。 Volatile - 与处理器缓存有关,如果我使用它,所有线程都不会创建对象的副本。所以,在我看来,如果我运行这段代码,我将获得正确的计数器值 (40000)。但我错了!

public class Main {

private static volatile Integer counter = 0;

public static void main(String[] args) throws InterruptedException {
Thread thread = new Counter();
Thread thread2 = new Counter();
thread.start();
thread2.start();
thread.join();
thread2.join();
System.out.println(counter);
}


public static class Counter extends Thread{
@Override
public void run() {
for (int i = 0; i < 20000; i++) {
synchronized (counter){
counter++;
}
}
}
}
}

但是如果我使用同步方法,我会得到正确的结果:

public class Main {

private static volatile Integer counter = 0;

public static void main(String[] args) throws InterruptedException {
Thread thread = new Counter();
Thread thread2 = new Counter();
thread.start();
thread2.start();
thread.join();
thread2.join();
System.out.println(counter);
}

public synchronized static void increment(){
counter++;
}

public static class Counter extends Thread{
@Override
public void run() {
for (int i = 0; i < 20000; i++) {
increment();

}
}
}
}

那么问题 - 为什么 synchronized 对 Integer 对象不起作用??

最佳答案

你误解了几件事:

  1. volatile 与 CPU 缓存无关。所有现代处理器都采用多级 CPU 缓存,对应用程序完全透明,因此应用程序不必关心它们是否从 L1、L2、L3、RAM 等获取。这是通过 CPU 实现一些缓存来实现的-一致性协议(protocol),例如MESI或其变体。那么 volatile 做了什么呢?它会阻止某些编译器优化。例如,如果您读取一个变量的值一次,而没有 volatile ,编译器可能会优化掉对该变量的任何后续读取,因为它假定它可能不会改变。使用 volatile,它不会删除那些额外的读取。

  2. synchronized 关键字使用某个对象作为锁,但在您的情况下,您正在更改该对象。因此,让我们假设线程 1 锁定在 Integer(0) 上,然后由于自动装箱,++ 操作将对象更改为 Integer(1)。您的第二个线程可以自由获取该锁,因为它没有被任何人持有。

  3. 锁定/同步字符串(因为它们可以是 interned)或 Boolean 或 Integer 等是非常糟糕的主意。程序的某些部分尝试获取同一实例上的锁,尽管从他们的角度来看它应该是不同的实例。 boolean 值 true/false 被缓存。从 -128 到 +127 的自动装箱整数被缓存,因此如果您可能遇到与 interned 字符串相同的问题。

因此对于同步,最好使用适当的锁并避免使用 synchronized 词。我什至会更进一步说这是 Java 中的一个错误

关于java - 为什么 volatile 加上 synchronized 不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67867528/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com