为什么我为下面给出的程序获得不同的输出?

时间:2015-10-31 15:02:24

标签: java multithreading

对于此代码,数字从1-10打印为线程t1,之后打印为线程t2

class Synchtest {
    public static void main(String args[]) {
        synchtest2 a = new synchtest2();
        Thread t1 = new Thread(a);
        Thread t2 = new Thread(a);
        t1.start();
        t2.start();
    }
}

class synchtest2 extends Thread {

    public synchronized void run() {
        for (int i = 0; i <= 10; i++) {
            System.out.println(i);
            try {
                sleep(1000);
            } catch (Exception e) {
            }
        }
    }
}

但是对于下面的代码,他们打印为00 11 22 33 44 55,依此类推。

class Synchtest {
    public static void main(String args[]) {

        synchtest2 t = new synchtest2();
        synchtest2 t2 = new synchtest2();
        t.start();
        t2.start();
    }
}

class synchtest2 extends Thread {

    public synchronized void run() {
        for (int i = 0; i <= 10; i++) {
            System.out.println(i);
            try {
                sleep(1000);
            } catch (Exception e) {

            }

        }
    }
}

3 个答案:

答案 0 :(得分:1)

在第一个示例中,两个线程使用单个synchtest2实例作为其Runnable,并且其run()方法已同步。因此,第一个启动的线程获取此唯一实例的监视器,打印所有数字,然后释放监视器,允许第二个线程运行。

在第二个示例中,您有两个不同的实例,每个线程都使用自己的实例。因此,他们并行获取自己的监视器(因为每个对象都有自己的监视器),并且同时愉快地打印它们的数字。

答案 1 :(得分:0)

由于它们是两个独立的线程,因此它们并行运行。

这意味着,他们基本上同时打印每个数字,这将它们放在同一行,而不是在两者之间插入换行符。

如果你在启动线程之间稍微延迟,你会看到它们张贴在不同的行上。

在您的第一个示例中,由于您对两个线程使用相同的类,因此在进入第二个线程之前它将完成一个。如果您希望获得类似的结果,则必须等待第一个线程完成才能触发第二个线程。

答案 2 :(得分:0)

在第一个示例中,您使用相同的Thread实例两次。它们不会并行运行,因为一次只允许一个线程进入实例的run()例程。

第二次创建两个不同的synchtest实例,创建两个不同的线程,可以并行运行。