这看起来像我能想象的最简单的可运行
public class StringShower implements Runnable{
private volatile boolean running = true;
private String text;
public StringShower(String text){
this.text = text;
}
@Override
public void run() {
while (running) {
try {
System.out.println("Current text" + text);
if(text != null){
showText(text);
}
Thread.sleep((long) 1000);
} catch (Exception e) {
running = false;
}
}
}
private void showText(String text2) {
System.out.println("Current Text " + text2);
}
public void stopRunning() {
this.running = false;
}
这是开始的课程
public class ChangeString {
private static String changeme;
public static void main(String[] args) {
Thread thread1 = new Thread(new StringShower(changeme));
thread1.start();
changeme = "changed";
}
}
在阅读了很多例子之后,我仍然无法弄清楚为什么线程中的String
永远不会更新。任何人都可以解释原因吗?
答案 0 :(得分:4)
changeme = "changed";
更改了main方法中的String
changeme
个引用,它不会更改text
实例中引用的引用StringShower
。
由于String
也是不可变的并且无法更改,因此您可以使用另一个获取并设置String
的类来包装该字符串,并传递此包装类的引用。
如果您确实创建了这样的包装类,请确保get和set是同步的,以便每个线程在查询时都能看到最新引用所引用的内容。
答案 1 :(得分:2)
除了NESPowerGlove所说的。字符串是不可变的。您永远不能更改字符串的值。每当您尝试更新它或将其设置为某些内容时,您要么创建新对象,要么只引用现有字符串。
答案 2 :(得分:0)
StringShower
在其null
字段中包含对text
的引用。怎么样?
changeMe
初始化为null
,这就是您传递给StringShower
并分配给text
的内容。然后,您更新changeMe
指向的引用,但这对text
指向的内容(仍为null
)没有影响。
如果您想操纵text
字段,请考虑使用setter。和/或确保已传递给StringShower
构造函数的文本已分配。
答案 3 :(得分:0)
使用与text
指向同一对象的引用值初始化changeme
。稍后您更改changeme
中保存的引用,但这不会影响text
,因为您没有更改它们指向的对象,但在changeme
中保存了新引用。
Java是按值传递的。有关更深入的解释,请参阅Is Java "pass-by-reference" or "pass-by-value"?。