ExecutorService - 在 Eclipse 中调试和运行的不同输出

ExecutorService - A different output from debug and from run in Eclipse

提问人:Scripta14 提问时间:11/8/2019 更新时间:11/8/2019 访问量:757

问:

我正在使用 Executor java 框架编写代码,并且正在 Eclipse 上测试我的代码,但我看到了一件奇怪的事情。在 eclipse 上使用调试模式,我可以在控制台上打印输出,或者更好的是,当我使用调试模式步入 (F5) 时,我可以在控制台上打印输出,但是如果我使用调试模式,使用步进返回(F7)或运行应用程序,它会在控制台上不打印任何内容。

在我之前使用调试模式步入(F5)的输出下方:

mapBuffer 
[[B@1af2d44a, [B@18d87d80, [B@618425b5, [B@58695725, [B@543588e6, [B@f5acb9d, [B@4fb3ee4e]

之后使用调试模式和步骤返回(F7)或运行应用程序:

mapBuffer 
[]

使用相同的代码,我有两个不同的输出。

public boolean readPieceCount() throws IOException {

        //byte[] buffer = null;
        SortedMap<Integer,byte[]> mapBuffer=new TreeMap<>();    


        ExecutorService executor = Executors.newFixedThreadPool(1);
        executor.submit(() -> {

        for (Integer i=0; i<NUMFILES;i++) 
        {
         Path path = Paths.get(pathPieceCount+"pieceCount"+(i+1)+".csv");
          if(Files.exists(path, LinkOption.NOFOLLOW_LINKS)) 
          {
           byte[] buffer = null;
           try {
            buffer = Files.readAllBytes(path);
                mapBuffer.put(i+1, buffer);
           } catch (IOException e) {
             System.out.println("Exception on readPieceCount!!!");
           }
             }
        }
        });

       System.out.println("mapBuffer ");
       System.out.println(mapBuffer.values());
    executor.shutdown();
/*
more code
*/

这是我代码的一部分,我有问题。

我希望在所有模式下都有相同的结果。老实说,我昨天花了很多时间,但我不明白哪里出了问题。只是一个确认。当我运行这部分代码时,总是会在地图上得到相同的缓冲区序列,或者执行器可以改变序列吗?

Java 执行器服务

评论


答:

1赞 Amit Bera 11/8/2019 #1

调试多线程应用程序并不像单线程应用程序那样简单。调试模式下的应用程序输出将完全取决于放置断点的位置。在调试模式下,当它到达调试点时,执行该部分语句的线程将被挂起,其他线程将执行并完成其工作。这意味着您的整个应用程序将不会等待恢复挂起的线程。由于挂起的线程中可以有多个线程,因此您可以检查您以什么顺序恢复线程,以及所有线程是否恢复。

形成你的代码,在不知道你到底是如何调试的情况下,很难说出输出的确切原因是什么。但看起来您的主/父线程
在您恢复/开始/完成其他执行器服务线程之前正在打印值。
mapBuffer

3赞 NotGaeL 11/8/2019 #2

你在这里处理的是并发性,所以基本上如果你的主线程在完成第一个线程之前命中行,你将打印一个空数组。在打印之前设置一个等待条件以同步代码,在打印出生成的 .System.out.println(mapBuffer.values());executor.submit(() -> {}mapBuffer.putSortedMap

查看如何使用 ExecutorService 等待所有线程完成?,了解如何正确执行此操作的一个很好的示例。

评论

2赞 user85421 11/8/2019
更糟糕的是,在执行打印时,提交的任务可能尚未启动
0赞 Scripta14 11/8/2019
谢谢,我已经解决了我的问题。我可以问你另一段代码吗?在这种情况下,我应该在 ExecutorService 中使用带有 try\catch 条件的代码。我可以将此代码添加到我之前的代码中以便向您展示代码吗?
0赞 NotGaeL 11/11/2019
同样,如果你的线程引发了异常,你可以在线程本身上提供它,或者在你的 catch 块中使用某种信号来在你的主线程中处理它。任务对象上的简单标志可以完成这项工作,具体取决于您的要求。然后,如果您想稍后处理该问题,可以设置您的捕获块。executionSuccessthis.executionSuccess=false
1赞 Scripta14 11/11/2019
我在线程本身上提供了异常。非常感谢您的帮助。