gpt4 book ai didi

java - 对象的成员不需要 volatile 而只需要原始成员吗?

转载 作者:行者123 更新时间:2023-11-30 06:48:36 25 4
gpt4 key购买 nike

我的代码是

package threadrelated;
import threadrelated.lockrelated.MyNonBlockingQueue;

public class VolatileTester extends Thread {

MyNonBlockingQueue mbq ;

public static void main(String[] args) throws InterruptedException {

VolatileTester vt = new VolatileTester();
vt.mbq = new MyNonBlockingQueue(10);
System.out.println(Thread.currentThread().getName()+" "+vt.mbq);
Thread t1 = new Thread(vt,"First");
Thread t2 = new Thread(vt,"Secondz");
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(Thread.currentThread().getName()+" "+vt.mbq);

}
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+" before "+mbq);
mbq = new MyNonBlockingQueue(20);
try {
Thread.sleep(TimeUnit.SECONDS.toMillis(10));
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" after "+mbq);
}

}

输出是

main threadrelated.lockrelated.MyNonBlockingQueue@72fcb1f4
Secondz before threadrelated.lockrelated.MyNonBlockingQueue@72fcb1f4
First before threadrelated.lockrelated.MyNonBlockingQueue@72fcb1f4
Secondz after threadrelated.lockrelated.MyNonBlockingQueue@7100650c
First after threadrelated.lockrelated.MyNonBlockingQueue@7100650c
main threadrelated.lockrelated.MyNonBlockingQueue@7100650c

说明当First线程将成员变量赋值给new对象时,同样对其他线程可见。即使“mbq”未声明为易变的。

我使用断点来尝试不同的操作顺序。但我的观察是一个线程可以立即看到另一个线程的影响。

类成员 object 不需要 volatile 吗?它们总是与主存同步吗?仅原始成员变量(int、long、boolean 等?)需要 volatile

最佳答案

它对引用和基元一样必要。您的输出没有显示可见性问题这一事实并不证明不存在。一般来说,很难证明不存在并发错误。但这里有一个简单的反证,显示了 volatile 的必要性:

public class Test {
static volatile Object ref;

public static void main(String[] args) {
// spin until ref is updated
new Thread(() -> {
while (ref == null);
System.out.println("done");
}).start();

// wait a second, then update ref
new Thread(() -> {
try { Thread.sleep(1000); } catch (Exception e) {}
ref = new Object();
}).start();
}
}

该程序运行一秒钟,然后打印“完成”。删除 volatile 并且它不会终止,因为第一个线程永远不会看到更新的 ref 值。 (免责声明:与任何并发测试一样,结果可能会有所不同。)

关于java - 对象的成员不需要 volatile 而只需要原始成员吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44038816/

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