多线程程序每次都有不同的输出

时间:2013-02-06 11:38:22

标签: java multithreading

当我尝试多次执行以下multhiThreading代码时,输​​出与前一个不同。是因为JVM行为还是可能是其他原因。请帮我一个。

program:


package example.thread.com;

class MyThread1 implements Runnable {
    Thread t;

    MyThread1(String s) {
        t = new Thread(this, s);
        t.start();
    }

    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println("Thread Name  :"
                    + Thread.currentThread().getName());
            try {
                Thread.sleep(2000);
            } catch (Exception e) {
            }
        }
    }
}


public class RunnableThread1 {
    public static void main(String args[]) {
        System.out.println("Thread Name :" + Thread.currentThread().getName());
        MyThread1 m1 = new MyThread1("My Thread 1");
        MyThread1 m2 = new MyThread1("My Thread 2");
    }
}

输出:如果我第一次跑

Thread Name :main
Thread Name  :My Thread 1
Thread Name  :My Thread 2
Thread Name  :My Thread 1
Thread Name  :My Thread 2
Thread Name  :My Thread 2
Thread Name  :My Thread 1
Thread Name  :My Thread 1
Thread Name  :My Thread 2
Thread Name  :My Thread 1
Thread Name  :My Thread 2

输出:如果我第二次运行

Thread Name :main
Thread Name  :My Thread 2
Thread Name  :My Thread 1
Thread Name  :My Thread 2
Thread Name  :My Thread 1
Thread Name  :My Thread 2
Thread Name  :My Thread 1
Thread Name  :My Thread 1
Thread Name  :My Thread 2
Thread Name  :My Thread 1
Thread Name  :My Thread 2

输出:如果我第三次运行

Thread Name :main
Thread Name  :My Thread 1
Thread Name  :My Thread 2
Thread Name  :My Thread 2
Thread Name  :My Thread 1
Thread Name  :My Thread 1
Thread Name  :My Thread 2
Thread Name  :My Thread 2
Thread Name  :My Thread 1
Thread Name  :My Thread 2
Thread Name  :My Thread 1
像这样请建议.....

6 个答案:

答案 0 :(得分:2)

这正是这个例子的要点。它表明线程是随心所欲地安排的,并且不保证输出按顺序发生。

在其他编程语言和系统中,期望损坏的输出是不合理的,例如:

Thread Name :main
Thread Name  :My Thread 1
Thread NThread Name  :My Thread 2ame  :My Thread 2
Thread Name  :My Thread 1
Thread Name  :My Thread 2
Thread Name  :My Thread 1
ThreaThread Name  :My d Name  :My ThrThread 2ead 1
Thread Name  :My Thread 2
Thread Name  :My Thread 1

答案 1 :(得分:0)

您有两个并行运行的线程,并且会多次打印它们的名称。根据许多因素,线程1可能首先启动,也可能是线程2.这或多或少是随机的。

然后睡眠没有非常精确的分辨率,因此一个线程可能会睡觉2001毫秒而另一个线程睡眠时间为1999毫秒 - 再一次这将是相当随机的。

注意:您不应该从构造函数中启动线程,最好执行以下操作:

MyThread1 m1 = new MyThread1("My Thread 1");
new Thrad(m1).start();

并删除MyThread1中对线程的所有引用 - 您可以将MyRunnable1重命名为一致。

答案 2 :(得分:0)

我认为你应该阅读JAVA的多线程和并发概念。首先阅读概念然后用代码实际操作总是一个很好的做法

答案 3 :(得分:0)

  

这是因为JVM行为......

是。 Java线程的许多方面(以及其他语言中的线程)都是non-deterministic。也就是说,它们无法预测,并且根据您无法控制的因素而有所不同。

因此,当您编写多线程应用程序时,您需要确保它不依赖于这些非确定性点之一的正确性。

在这种情况下,非决定论源于许多来源。例如:

  • 当您致电thread.start()时,未指定thread是否会在呼叫返回前实际开始执行指令。

  • 当您致电thread.sleep(2000)时,线程休眠的实际时间长度至少 2000毫秒。

  • 如果可以运行多个活动线程,则无法预测运行哪些(甚至多少个)。它取决于操作系统级别的线程调度程序。

答案 4 :(得分:0)

MyThread1中的run()方法我们同时在2个不同的线程中运行。 每个线程计数到5,每个计数打印其名称。 写入输出的操作是原子操作,这意味着一次只能有一个线程可以写入。因此,当线程准备好写入,但另一个线程首先到达那里时,它必须等到另一个线程完成写入才能开始写入。 没有办法告诉哪个线程会先到达那里,所以每次都不同。

想象一下,有2个人要求在纸上写下他们的名字5次。只有一点纸,他们必须分享它。为了写出他们的名字,他们首先得到了一点纸。如果对方拥有它,他们会等待。当他们写完一次名字后,他们就放弃了一点纸。 当两个人都准备好再次写下他们的名字而且没有人有一点纸时,那是第一次得到它的随机机会。

每次都有不同的结果......

答案 5 :(得分:0)

您看到的效果仅部分是JVM行为的结果。 JVM只创建线程并启动它们。操作系统负责决定哪个线程在哪个处理器上运行。您的线程将争夺使用处理器,而不仅仅是相互之间的处理器,而是计算机正在进行的所有工作。

当线程休眠时,它将停止成为可以使用处理器的可运行线程。当它到达睡眠时间结束时,它会回到可运行的状态,并争夺处理器的使用。在此之后的某个时间,操作系统会选择它作为在处理器上运行的线程,它将继续计算。它保持处理器直到它终止,休眠,必须等待其他东西,或操作系统决定它是另一个线程。

没有理由期望两个线程之间的顺序从运行到运行是相同的。编写提供一致结果的多线程程序需要付出一些努力。

我建议从一些关于多线程编程的基础教程开始。当您准备好更深入地了解该主题时,我建议Java Concurrency in Practice