请解释以下代码的工作原理

时间:2012-10-07 08:36:27

标签: multithreading thread-safety

我有以下代码,但它的输出不符合我的预期:

public class ThreadManager {
    public static void main(String[] args) {
        Resource sharedResource = new Resource();
        new Thread(new MyThread(sharedResource)).start();
        new Thread(new MyThread(sharedResource)).start();
    }
}

class MyThread implements Runnable{
    Resource rs = null;
    public MyThread(Resource param) {
        this.rs = param;
    }
    @Override
    public void run() {
        this.rs.add(Thread.currentThread().getName());
        System.out.println(this.rs.str);
    }
}

class Resource{
    StringBuilder str = new StringBuilder();
    public void add(String text){
        str.append(text);
    }
}

输出是:

Thread-0Thread-1
Thread-0Thread-1

但是如何...

如果首先执行线程0,则输出应为

Thread-0
Thread-0Thread-1

但是这里的问题是第一行输出中的thread-1。

2 个答案:

答案 0 :(得分:2)

  

此处如果首先执行线程0,则输出

是什么让你认为只是因为你首先开始线程0,它会首先进入add方法调用?即使一个线程 首先进入add调用,也不意味着它将在之前到达 next 语句(System.out.println)另一个帖子有机会打电话给add。看起来就是这种情况:

  • Thread0调用add
  • Thread1调用add
  • Thread0调用System.out.println(this.rs.str)
  • Thread1调用System.out.println(this.rs.str)

(这有点手工波浪,因为那些不是原子操作,但它可能是流动的。)

想象一下,你的两条线是跑道上的运动员 - 你开始它们的顺序不一定与它们越过终点线的顺序相同。

另请注意,StringBuilder并非设计为安全,无法从多个线程进行访问。

答案 1 :(得分:0)

它不像看起来那么简单。线程正在printLn()内的锁上交换,