在学习Java并发时遇到了这种我无法解释的行为:
public class ThreadInterferrence implements Runnable {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(new ThreadInterferrence());
t.start();
append("1", 50);
t.join();
System.out.println(value);
}
private static String value = "";
public void run() {
append("2", 50);
}
private static void append(String what, int times) {
for (int i = 0; i < times; ++i) {
value = value + what;
}
}
}
为什么程序会生成随机字符串?更重要的是为什么输出长度变化?它不应该总是100个字符吗?
输出示例:
22222222222222222222222222222222222222222222222222
1111111111111111111111111111112121112211221111122222222222222
等。
答案 0 :(得分:4)
原因是你有两个主题。
正在调度运行哪个线程的操作系统(OS),因此您会看到随机输出。所以在你的情况下,操作系统安排你的runnable运行一段时间打印1然后尝试运行主线程,然后打印2。
答案 1 :(得分:3)
关于更新问题的主题(为什么输出的长度会有所不同?不应该总是100个字符?)
行为将是不可预测的,因为重新分配新String不是原子的。请注意,字符串是不可变的,您可以继续为变量重新赋值。所以发生了什么是一个线程获取值,另一个线程也获取值,一个线程添加一个字符并再次写入,但另一个线程具有旧值。现在您丢失了数据,因为其中一个线程的更新丢失了。
在这种情况下,您可以使用线程安全的StringBuffer,或者添加我确定您将了解的同步。
答案 2 :(得分:1)
[问题]更重要的是,为什么输出长度会有所不同?
[答案]变量&#34;值&#34;正在被多个线程使用(主线程以及其他线程)。因此,用于改变变量状态的方法需要是线程安全的,以控制最终长度。这里情况不同。