首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java execuetorService运行得太快了?

Java execuetorService运行得太快了?
EN

Stack Overflow用户
提问于 2017-07-06 06:36:37
回答 2查看 164关注 0票数 0

由以下代码编写

代码语言:javascript
复制
    ExecutorService executorService = Executors.newFixedThreadPool(3)
    for (int i=0; i<10; i++){
            executorService.execute(new Runnable() {
                @Override
                void run() {
                    try {
                        Thread.sleep(1*1000)
                        System.out.println("Thread " + Thread.currentThread().getName() + " processing item " + i)
                    } catch (InterruptedException e) {
                        e.printStackTrace()
                    }
                }
            })
    }

--我期望输出如下:

线程池-1-线程-2处理项1

线程池-1-线程-3处理项2

线程池-1-线程-2处理项3

线程池-1-线程-3处理项4

线程池-1-线程-2处理项5

线程池-1-线程-2处理项7

线程池-1-线程-3处理项6

线程池-1-线程-2处理项8

线程池-1-线程-3处理项9

线程池-1-线程-1处理项0

,但事实证明是:

线程池-1-线程-1处理项10

线程池-1-线程-1处理项10

线程池-1-线程-1处理项10

线程池-1-线程-1处理项10

线程池-1-线程-1处理项10

线程池-1-线程-1处理项10

线程池-1-线程-1处理项10

线程池-1-线程-1处理项10

线程池-1-线程-2处理项10

线程池-1-线程-3处理项10

正确的输出是在executorService.exeute方法之前添加一个temp变量。这里来了一个问题,意外输出的原因是什么?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-07-06 06:41:14

  • 首先,您的代码不会编译(至少在Java中不会编译,在Groovy中可能会这样做)
  • 'i‘不能在块中使用,因为它不是最终的,也不能是最终的,因为它在for-循环中使用。

您所说的“正确的输出是通过在executorService.exeute方法之前添加一个临时变量”是什么意思?

而且,您也不应该期望这样的输出。你没有得到这样的命令的保证,例如,我得到:

Thread pool-1-thread-1 processing item 0 Thread pool-1-thread-2 processing item 1 Thread pool-1-thread-3 processing item 2 Thread pool-1-thread-3 processing item 5 Thread pool-1-thread-1 processing item 3 Thread pool-1-thread-2 processing item 4 Thread pool-1-thread-1 processing item 7 Thread pool-1-thread-2 processing item 8 Thread pool-1-thread-3 processing item 6 Thread pool-1-thread-1 processing item 9

通过使用此代码:

代码语言:javascript
复制
    ExecutorService executorService = Executors.newFixedThreadPool(3);
    for (int i = 0; i < 10; i++) {
        final int j = i;
        executorService.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(1 * 1000);
                    System.out.println("Thread "
                            + Thread.currentThread().getName()
                            + " processing item " + j);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
    }
}
票数 1
EN

Stack Overflow用户

发布于 2017-07-06 12:38:36

所有的运行库都共享相同的i实例。

当它们运行时,这个变量的值为10

因此输出。

如果使用闭包,每个runnable都将得到一个新的i实例,并得到预期的输出:

代码语言:javascript
复制
ExecutorService executorService = Executors.newFixedThreadPool(3)
10.times { i ->
   executorService.execute { ->
       Thread.sleep(1000)
       println "Thread ${Thread.currentThread().getName()} processing item $i"
   }
}
executorService.shutdown()

但它们不会按你所期望的顺序排列,因为线程.

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44941436

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档