我正在尝试多线程,在运行一小段代码时遇到了不一致的情况。下面的代码应该打印出 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();
}
}
Output: 123231231132123231321
Output: 123213123123213213213
Output: 123231213213231231213
我不明白的是,它在第一次通过时正确运行(打印“123”),但在第二次通过时打印“231”。如果线程正在打印一个字符,则 hibernate 1 秒,然后重复。每次运行代码时,模式 123123... 不应该保持一致,或者至少遵循前 3 个字符的模式吗?
最佳答案
The following code should print out 123123
不一定。您基本上应该永远依赖于它们之间没有同步的线程来唤醒并以任何特定顺序执行。
让我们采用第一个字符输出:不能保证那会是 1。是的,您首先启动打印 1 的线程,但这并不意味着这是第一个打印 1 的线程。实际上会首先开始执行 run
- 即使确实如此,也不意味着这是第一个执行 System.out.print
调用的线程。
考虑到相当长的 sleep 时间,我希望(但理想情况下不依赖)输出是 7 个“ block ”的序列,其中每个“ block ”由字符“123”组成一些排列。但是,如果您有三个线程“大致”同时进入 hibernate 状态一秒钟,那么您不应该期望它们一定会按照 1、2、3 的顺序醒来,即使它们确实如此,其中一个可能会在循环体内抢占另一个。
在一台非常非常慢的机器上,即使这样的期望也是无效的 - 想象一下它需要 0 到 20 秒之间的随机时间来调用 charAt
- 不太可能,但它是一个 可行的思想实验。此时,其中一个线程可能会在另一个线程设法打印任何东西之前先完成其输出。
线程被设计为独立的 - 如果您希望它们以协调的方式工作,您必须自己指定该协调。有很多工具可以完成这项工作,但不要指望它会神奇地发生。
关于java - 为什么线程运行不一致?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30781604/