Java 多线程线程随机终止

Java multi-threading threads terminating at random

在学习 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;
        }
    }
}

为什么程序会生成运行dom字符串?更重要的是为什么输出的长度会变化?它不应该总是恰好 100 个字符吗?

输出示例:

22222222222222222222222222222222222222222222222222
1111111111111111111111111111112121112211221111122222222222222

等..

原因是您有两个线程。

  • 附加到相同值字符串的主线程
  • ThreadInterferrence 再次附加到相同值字符串的线程。

操作系统 (OS) 正在调度哪个线程到 运行,因此您会看到随机输出。因此,在您的情况下,OS 将您的 运行nable 暂时安排到 运行,它会打印 1,然后尝试 运行 主线程,而主线程又会打印 2。

[问题]更重要的是为什么输出的长度会变化?

[Answer] 变量"value" 被多个线程(主线程和其他线程)使用。因此,用于更改变量状态的方法需要是线程安全的,以控制最终长度。这里情况不同。

关于您更新的问题的主题(为什么输出的长度不同?它不应该总是恰好是 100 个字符吗?)

行为将不可预测,因为新 String 的重新分配不是原子的。请注意,字符串是不可变的,您会不断将值重新分配给变量。所以发生的事情是一个线程获取值,另一个线程也获取值,一个线程添加一个字符并再次写入,但另一个线程也使用旧值。现在您正在丢失数据,因为来自其中一个线程的更新丢失了。

在这种情况下,您可以使用线程安全的 StringBuffer,或者添加我相信您会了解的同步。