循环中线程的不同结果,它们在java中是如何工作的?

循环中线程的不同结果,它们在java中是如何工作的?,java,multithreading,for-loop,Java,Multithreading,For Loop,当我在for循环中创建多个线程时,如果我采用不同的方法,则会有不同的结果 private List<Future<Integer>> futureList = new ArrayList<>(); void testThread() throws ExecutionException, InterruptedException { ExecutorService executorService = new ThreadPoolExecu

当我在for循环中创建多个线程时,如果我采用不同的方法,则会有不同的结果

    private List<Future<Integer>> futureList = new ArrayList<>();
    void testThread() throws ExecutionException, InterruptedException {
    ExecutorService executorService = new ThreadPoolExecutor(4, 4, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(100 * 1024));
    for (int i = 0; i < 10000; i++) {
            int finalI = i;
            Future<Integer> future = executorService.submit(new Callable<Integer>() {
                @Override
                public Integer call() throws Exception {
                    System.out.println("call ==" + finalI);
                    return finalI;
                }
            });
            doS(future);
            System.out.println("for end ==:"+finalI);
        }
        System.out.println("---------====------------");
        executorService.shutdown();
    }

    private void doS(Future<Integer> future) throws ExecutionException, InterruptedException {
        this.futureList.add(future);
    }
但是,如果我更改方法doS():

“doS()”的方法不属于“executorService”,也不是线程方法,因此循环是否会按顺序工作?为什么它们以不同的方式工作? 谢谢。

get(future)函数使其调用的线程等待future完成并返回结果。因此,它将多线程代码转换为一个循环,启动一个线程,然后在启动下一个线程之前等待它完成。这几乎消除了使用线程的必要性

您的原始版本没有等待时间,因此所有线程都会生成,并将按照操作系统决定的任何顺序启动


如果你需要事情按照特定的顺序发生,不要使用线程。你不能强制执行。如果你想知道为什么第一个版本是以随机顺序出现的,那是因为操作系统会在它认为最好的时候调度线程并在它们之间切换,而没有办法排序。它们可以顺序发生,也可以在不同的内核/处理器中同时发生,或者以任意随机顺序发生。这是使线程需要协调的多线程变得困难的原因之一。

future.get()
被阻塞,因此您在这里有一个顺序排序。@SeelenVirtuse非常感谢!我花了很多时间思考。
for end ==:0
for end ==:1
for end ==:2
call ==0
for end ==:3
call ==1
for end ==:4
call ==4
call ==2
call ==5
call ==3
for end ==:5
for end ==:6
    private List<Future<Integer>> futureList = new ArrayList<>();
    @Test
    void testThread() throws ExecutionException, InterruptedException {
        ExecutorService executorService = new ThreadPoolExecutor(4, 4, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(100 * 1024));
        for (int i = 0; i < 10000; i++) {
            int finalI = i;
            Future<Integer> future = executorService.submit(new Callable<Integer>() {
                @Override
                public Integer call() throws Exception {
                    System.out.println("call ==" + finalI);
                    return finalI;
                }
            });
            doS(future);
            System.out.println("for end ==:"+finalI);
        }
        System.out.println("---------====------------");
        executorService.shutdown();
    }

    private void doS(Future<Integer> future) throws ExecutionException, InterruptedException {
        Integer integer = future.get();
    }

call ==0
for end ==:0
call ==1
for end ==:1
call ==2
for end ==:2
call ==3
for end ==:3
call ==4
for end ==:4
call ==5
for end ==:5
call ==6
for end ==:6