java - java中新建线程的执行顺序是怎样的

标签 java multithreading java-threads

class Test {
    boolean isFirstThread = true;

    private synchronized void printer(int threadNo) {
        if(isFirstThread) {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        isFirstThread = false;
        System.out.println(threadNo);
   }

   public void starter() {
        new Thread(){
            @Override()
            public void run() {
                printer(0);
            }
        }.start();

        new Thread(){
            @Override()
            public void run() {
                printer(1);
            }
        }.start();

        new Thread(){
            @Override()
            public void run() {
                printer(2);
            }
        }.start();

        new Thread(){
            @Override()
            public void run() {
                printer(3);
            }
        }.start();
    }
}

在上面的代码中,当我从 main 调用 starter 时。我创建了四个新线程来调用同步函数。我知道无法预测线程的执行顺序。除非他们都等待一段时间,以便第一个线程可以完成并从同步块(synchronized block)中出来。在这种情况下,我希望所有线程都保持在队列中,所以我希望得到的答案是
0
1
2
3
但一直(我运行程序超过 20 次)我得到的输出是
0
3
2
1
这意味着线程被保存在堆栈而不是队列中。为什么会这样?谷歌结果中的每个答案都说它是一个队列,但我把它作为一个堆栈。我想知道将线程保存在堆栈(这是违反直觉的)而不是队列中的原因?

最佳答案

线程启动的顺序由操作系统决定,Java 语言规范中没有指定。您在主线程中调用 start,但是何时分配新线程以及何时开始处理其 Runnable 或 run 方法由操作系统的调度程序决定。

注意不要依赖线程碰巧启动的顺序。

关于java - java中新建线程的执行顺序是怎样的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36801703/

相关文章:

java - 并行迭代大 HashMap

java - 将毫秒转换为时间

c# - 在另一个线程中调用函数 C#

java - 配置线程池用于调度任务及其取消

java - 与 HikariCP 的并发

java - 如何在Java中并行处理对象列表

java - 停止 Spring Batch 中运行的线程

java - 从 Java 访问 gradle 资源

java - 为什么某些 Java 类可以访问我的 IntelliJ IDEA 项目中的图像,而 JavaFX 中的其他类则不能访问?

java - Electron 应用程序可以与 java 代码集成吗?