Java多线程线程随机终止

时间:2015-02-08 14:03:52

标签: java string multithreading concurrency terminate

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

等。

3 个答案:

答案 0 :(得分:4)

原因是你有两个主题。

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

正在调度运行哪个线程的操作系统(OS),因此您会看到随机输出。所以在你的情况下,操作系统安排你的runnable运行一段时间打印1然后尝试运行主线程,然后打印2。

答案 1 :(得分:3)

关于更新问题的主题(为什么输出的长度会有所不同?不应该总是100个字符?)

行为将是不可预测的,因为重新分配新String不是原子的。请注意,字符串是不可变的,您可以继续为变量重新赋值。所以发生了什么是一个线程获取值,另一个线程也获取值,一个线程添加一个字符并再次写入,但另一个线程具有旧值。现在您丢失了数据,因为其中一个线程的更新丢失了。

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

答案 2 :(得分:1)

[问题]更重要的是,为什么输出长度会有所不同?

[答案]变量&#34;值&#34;正在被多个线程使用(主线程以及其他线程)。因此,用于改变变量状态的方法需要是线程安全的,以控制最终长度。这里情况不同。