有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

使用不同线程时,源代码运行的java顺序

当我第一次开始学习Java时,我了解到代码从顶部读取到底部。我想你们都明白,不需要编写代码来解释这个问题

但是当我使用multi-threading时会发生什么呢?假设我有一个简单的例子:

public class Tester {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        for (int i = 0; i < 5; i++) {
            executorService.execute(new WorkingClass());
        }
        System.out.println("rest od code..");
        executorService.shutdown();
    }
}

class WorkingClass implements Runnable{
    @Override
    public void run() {
        System.out.println("working");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

我正在使用singleThreadExecutor,因此1个线程应该完成5个任务。我希望我的for循环将首先运行,在控制台中打印"rest od code.."之前至少打印一个"working"。我错了。我的结果总是这样:

rest od code..
working
working
working
working
working

有人能告诉我,在'rest of code'之前,控制台中是如何至少打印一个'working'的吗?有没有可能代码运行得太快,以至于在到达('rest of code')之前没有机会实际运行任何run() method

[注]如有任何修改,将不胜感激


共 (2) 个答案

  1. # 1 楼答案

    线程正在并发执行(主线程和工作线程),尝试在println in main方法之前暂停主线程执行一段时间,结果会有所不同

    Thread.sleep(1000);
    System.out.println("rest od code..");
    executorService.shutdown();
    

    重复运行,并且很可能在主线程暂停时执行工作线程

    预期的是记忆一致性效应:

    “在将可运行或可调用任务提交给ExecutorService之前,线程中的操作发生在该任务执行任何操作之前,而该操作又发生在通过Future.get()检索结果之前。”

  2. # 2 楼答案

    不同的线程独立运行。无法保证主线程和它创建的任何“可运行程序”之间的相对顺序

    这与代码是否从上到下“读取”无关;对于执行来说,这不是一个有用的概念。下面是一个非自上而下执行的简单非线程示例:

       void method1() {
           method2();
           System.out.println("one");
       }
    
       void method2() {
           System.out.println("two");
       }
    

    回到当前的问题:您会注意到,‘execute’的documentation指的是在‘将来某个时候’运行Runnable

    实际上,这可能类似于在队列中放入一个条目,然后唤醒一个线程。让线程启动并运行通常需要比直线代码路径更多的机器指令

    所以,是的,你对“跑得这么快”的解释或多或少是正确的,只是“跑得这么快”并不是真的盲目地快