当我尝试多次执行以下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
像这样请建议.....
答案 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