为什么线程不能一直运行?

时间:2015-06-11 13:03:26

标签: java multithreading thread-sleep

我正在玩多线程,并且在运行一小段代码时遇到了不一致。以下代码应打印出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是否应该保持一致?

2 个答案:

答案 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的作用。