线程在执行期间被扰乱

时间:2013-01-07 17:52:38

标签: java multithreading threadpool

在下面的代码段中,我创建了3个线程并给它们一个数字来跟踪哪一个是哪个。当我执行程序时,输出是预期的,除了线程是随机排序的。我希望它们能够以与它们创建时相同的顺序出现。开始(1-2-3),而不是每次都得到一个混乱的结果。

这是为什么?

PrintTask对象创建一个随机sleep时间,并在完成睡眠时打印一条消息。代码很简单所以我不会发布它。当我使用ExecutorService而不是单独的线程对象时,会发生同样的事情。

public static void main(String[] args) {
    Thread thread1 = new Thread(new PrintTask("Thread 1"));
    Thread thread2 = new Thread(new PrintTask("Thread 2"));
    Thread thread3 = new Thread(new PrintTask("Thread 3"));

    System.err.println("Starting threads");

    thread1.start();
    thread2.start();
    thread3.start();

    System.err.println("Threads started, main ends\n");
}

输出:

  

线程2进入4907睡眠状态

     

线程1进入4779睡眠状态

     

线程3进入休眠状态537

     

线程3完成了睡眠

     

线程1完成睡眠

     

线程2完成了睡眠

4 个答案:

答案 0 :(得分:4)

  

我希望它们能够以与创建时相同的顺序出现。开始(1-2-3)

不,不保证线程执行的顺序。

答案 1 :(得分:1)

唯一的保证是(JLS 17.4.5):

  

在启动线程中的任何操作之前,对线程的start()调用发生。

但是无法保证何时涉及多个线程,因此您需要使用某种形式的同步来获得所需的输出。

答案 2 :(得分:1)

  

我希望它们能够以与创建时相同的顺序出现。开始(1-2-3)

没有提供此类保证。

答案 3 :(得分:1)

如何调度线程的运行取决于许多因素,包括任何框架调度程序,OS调度程序,硬件等。在没有任何显式协调的情况下,您不应该依赖于并发执行线程之间的某种操作顺序。在启动和实际执行第一条指令之间,调度程序很可能会将一个线程从CPU中取出。