如何用Java解释这个多线程程序的代码输出?

时间:2017-07-06 10:44:08

标签: java multithreading

我正在研究java中的多线程并编写以下代码。

    public class MulThread extends Thread
{
    public void run()
    {
        for(int i=1; i<5;i++)
        {
            try
            {
                Thread.sleep(500);
            }
            catch(Exception e){ System.out.println(e);}
            System.out.println(i);
        }
    }


public static void main(String [] args)
{
    MulThread t1 = new MulThread();
    MulThread t2 = new MulThread();
    MulThread t3 = new MulThread();

    t1.start();
    t1.run();
    t2.start();
    t2.run();

    t3.start();
    t3.run();

}
}

我和一些朋友讨论了这个,我得出的结论是输出应该是一个完整的混乱。但由于某种原因,编译器总是产生以下输出:

1
1
2
2
3
3
4
4
1
1
2
2
3
3
4
4
1
1
2
2
3
3
4
4

有人可以解释当线程到达调度程序时究竟发生了什么吗?为什么输出不是一堆乱丢1,2,3和4,每次在随机汤中重复6次?

我的一些导师告诉我这只是一个巧合,这取决于我的操作系统或其他东西,但我对此持怀疑态度。我运行代码超过10次,它总是产生相同的结果。

2 个答案:

答案 0 :(得分:1)

此:

t1.start();

根据需要启动线程。线程机制将调用run()

但你接着称之为:

t1.run();

直接调用run()方法 并在运行时阻止主线程(因为您只是调用阻塞方法)。你不需要这个。简单地start()和您的新线程将按预期运行(与主线程分开)。

请注意,在这些情况下直接致电run()通常是不寻常的,并且表明存在混淆!

在这些情况下(via Thread.currentThread().getName())打印线程名称以查看正在进行的操作(并且可能命名您的线程,通过不同的Thread构造函数)

答案 1 :(得分:1)

当您调用t1.start()时,辅助线程会启动并运行run()方法。 当您调用t1.run()时,您正在主线程上执行run()方法。

这意味着t2.start();只会在t1.run();完成循环后执行,此时t1.start()创建的线程已经完成。

由于run()方法的循环包含大睡眠(半秒),因此t1.start()(在辅助线程上运行)和{{1}的输出很可能(在主线程上运行)将是交错的(因为睡眠足够时间让第二个线程获得控制并在第一个线程休眠时打印下一个输出)。

如果减少睡眠时间,您可能会看到不同的输出。