我正在玩多线程,并且在运行一小段代码时遇到了不一致。以下代码应打印出123123 ...但我得到的是
class RunnableDemo implements Runnable {
private String message;
RunnableDemo(String m) {
message = m;
}
public void run() {
try {
for (int i = 0; i < message.length(); i++) {
System.out.print(message.charAt(i));
Thread.sleep(1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class TestThread {
public static void main(String args[]) throws InterruptedException {
new Thread(new RunnableDemo("1111111")).start();
new Thread(new RunnableDemo("2222222")).start();
new Thread(new RunnableDemo("3333333")).start();
}
}
输出:123231231132123231321
输出:123213123123213213213
输出:123231213213231231213
我不能得到的是它在第一次通过时正确运行(打印&#39; 123&#39;)然后第二次通过它打印&#39; 231&#39;。如果线程正在打印char,则休眠1秒,然后重复。每次运行代码或至少遵循前3个字符的模式时,模式123123是否应该保持一致?
答案 0 :(得分:7)
以下代码应打印出123123
不一定。你基本上应该从不依赖于线程,它们之间没有同步,而是以任何特定的顺序唤醒和执行。
让我们取第一个字符输出:不能保证它是1.是的,你首先开始线程打印1但是这并不意味着第一个线程将首先实际开始执行run
- 或者即使它确实如此,这并不意味着它将成为第一个线程。得到System.out.print
电话。
考虑到相当长的睡眠时间,我会期望(但理想情况下不依赖)输出是7&#34; chunks&#34;的序列,其中每个&#34; chunk&# 34;由人物组成&#34; 123&#34;在一些排列中。但如果你有三条线程都会在#34;大约&#34;同时,你不应该期望它们必须以1,2,3的顺序唤醒 - 再次,即使它们这样做,其中一个可能在循环体内先占另一个。
在一台非常非常慢的机器上,即使这种期望也会无效 - 想象一下,在0到20秒之间需要一段随机的时间来调用charAt
- 不太可能,但它是可行的思想实验。此时,其中一个线程可以提前竞争并完成其输出,然后另一个线程设法打印任何。
线程被设计为独立的 - 如果您希望它们以协调的方式工作,您必须自己指定协调。这项工作有很多工具,但不要期望它会神奇地发生。
答案 1 :(得分:0)
您无法预测一次运行的程序CPU。在运行某个进程时,CPU会将进程转换为work
的小部分。因为一次运行多个进程。 CPU必须根据已实施的scheduling algorithm
进行安排。因此,简而言之,除非您以编程方式同步代码片段,否则无法预测下一步CPU的作用。