为什么线程在Java中顺序而不是同时运行

时间:2014-11-20 12:51:47

标签: java multithreading

以下代码中的线程似乎不会同时运行。但是,如果我将number更改为100万或将Thread.sleep(50);添加到循环中,则会同时运行。使线程休眠产生同质结果,同时将number增加到一百万,使每个线程在切换到其他线程之前打印50+行。这究竟是什么原因?

class RunnableDemo implements Runnable {
    int number = 4;
    private Thread t;
    private String threadName;
    RunnableDemo(String name) {
        threadName = name;
    }

    public void run() {
        System.out.println("----------");
        for (int i = number; i > 0; i--) {
            System.out.println("Thread: " + threadName + ", " + i);
        }

    }

    public void start() {
        System.out.println("Starting " + threadName);
            t = new Thread(this, threadName);
            t.start();

    }

}

public class Test {
    public static void main(String args[]) {

        RunnableDemo R1 = new RunnableDemo("Thread-1");
        RunnableDemo R2 = new RunnableDemo("Thread-2");

        R1.start();
        R2.start();
    }
}

这是number为4时代码生成的输出:

Starting Thread-1
Starting Thread-2
----------
Thread: Thread-1, 4
Thread: Thread-1, 3
Thread: Thread-1, 2
Thread: Thread-1, 1
----------
Thread: Thread-2, 4
Thread: Thread-2, 3
Thread: Thread-2, 2
Thread: Thread-2, 1

3 个答案:

答案 0 :(得分:4)

System.out.println 缓冲。因此,您无法使用它来测试线程的同时性。

答案 1 :(得分:2)

每条指令后线程都不会切换。线程完全可以在切换到另一个之前执行整个循环。添加睡眠会延长执行时间并增加上下文切换的可能性。

答案 2 :(得分:2)

假设您的机器有一个处理器。任何时候只能运行一个线程。如果多个进程正在运行,它们每个都会在处理器上接收一段时间,然后通过某种调度算法进行交换。

在您的情况下,当数字为4时,线程可以在换出之前完成其工作。完成后,处于等待状态的任何其他线程都可以运行。

  • T1>开始>执行>终止
  • T2>开始>执行>终止

当您将数量增加到一百万时,线程只能在调度程序分配的时间内执行其部分工作。一旦这个时间结束,它将由调度程序换出,并且处于等待状态的另一个线程将运行。

  • T1>开始>执行时间x>转移到等待状态
  • T2>开始>执行时间x>转移到等待状态
  • T1>简历>执行时间x>转移到等待状态
  • T2>简历>执行时间x>进入等待状态 ......
  • T1>终止
  • T2>终止

当您请求线程为x休眠时,可以将另一个线程移动到运行状态。

http://tinyurl.com/o8f3ogx