gpt4 book ai didi

java - 是否使引用变量易变,使其所有字段在 java 中也易变?

转载 作者:行者123 更新时间:2023-11-30 07:46:47 27 4
gpt4 key购买 nike

我读到过使引用变量可变,不会使其内部字段可变。但我尝试了下面的示例,其中看起来可变性质也应用于类的内部字段。

用户.java:-//将字段“flag”设置为 true 的用户类。

public class User {

private boolean flag=true;

public boolean isFlag() {
return flag;
}

public void setFlag(boolean flag) {
this.flag = flag;
}
}

MyRunnableThread1.java:-

这里我将“user”设置为volatile,而不是将其内部字段“flag”设置为volatile

子线程在“while(this.user.isFlag())”处不断循环。

public class MyRunnableThread1 implements Runnable {

private String threadName;
private volatile User user;

public MyRunnableThread1(String threadName,User user)
{
this.threadName=threadName;
this.user=user;
}

public User getUser() {
return user;
}

public void setUser(User user) {
this.user = user;
}

@Override
public void run() {

System.out.println("child thread:"+threadName+" started");

while(this.user.isFlag()) {

}
System.out.println("child thread:"+threadName+" finished");
}
}

ThreadDemo.java:-

在主线程中,我们将“User”对象的字段“flag”的值设置为false终止子线程中的循环

public class ThreadDemo {

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

System.out.println("main thread started");

User user=new User();
MyRunnableThread1 myRunnableThread1=new MyRunnableThread1("Thread1",user);
Thread t=new Thread(myRunnableThread1);
t.start();

try {
Thread.sleep(6000);
}
catch(Exception e) {
System.out.println("exception in sleep:"+e);
}

myRunnableThread1.getUser().setFlag(false);

System.out.println("main thread finished");
}
}

对/对:-

主线程启动子线程:Thread1 启动主线程完成子线程:Thread1完成

在上面的示例中,我在“MyRunnableThread1.java”类中将“user”变量设置为可变的。用户对象具有字段“标志”,在实例化时为真。启动不断执行循环的子线程后,主线程将用户对象的“flag”字段的值更改为false。但是这里字段“flag”不是易变的,而不是“user”引用变量是易变的。但仍然在这里,主线程中字段“flag”值的变化反射(reflect)在子线程中。它的行为就好像字段“flag”也是易 volatile 的。任何人都可以帮助解决上述问题吗??

最佳答案

来自 JLS:

8.3.1.4. volatile Fields

The Java programming language allows threads to access shared variables (§17.1). As a rule, to ensure that shared variables are consistently and reliably updated, a thread should ensure that it has exclusive use of such variables by obtaining a lock that, conventionally, enforces mutual exclusion for those shared variables.

The Java programming language provides a second mechanism, volatile fields, that is more convenient than locking for some purposes.

A field may be declared volatile, in which case the Java Memory Model ensures that all threads see a consistent value for the variable (§17.4).

但是对象不是变量。那么在您的情况下,一致的是 user 的值,这意味着所有线程都看到相同的引用,而不是它们观察到其内部内容的相同值。

关于java - 是否使引用变量易变,使其所有字段在 java 中也易变?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50375768/

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