0

I'm having a hard time interating a HashMap<String, Future<DPSImporterServiceImpl>>:

    for (Entry<String, Future<DPSImporterServiceImpl>> entry : map.entrySet()) {
        logger.debug("Thread: " + entry.getKey() + "/"
                + entry.getValue());
        Future<DPSImporterServiceImpl> fut = entry.getValue();
        try {
            DPSImporterServiceImpl imp = fut.get();
            logger.debug("Waiting over for: " + imp.toString());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }

My map contains two entries: {1435748953925=java.util.concurrent.FutureTask@705f23aa, 1435748971395=java.util.concurrent.FutureTask@761ea788}

Here's my logger outcome:

Thread: 1435748953925/java.util.concurrent.FutureTask@705f23aa
Waiting over for: Thread busy with 1435748971395.
Thread: 1435748971395/java.util.concurrent.FutureTask@761ea788
Waiting over for: Thread busy with 1435748971395.

As you can see the map gets iterated correctly because the log statements starting with Thread... are the ones from the map. The get() Method though does not work correctly as it is apparently getting called from the same object (both times from the second entry with the key 1435748971395).

This is quite confusing to me as the map definitely doesn't contain identic objects.

Could you tell me what might be wrong here? Thank you!

Erando
  • 811
  • 3
  • 13
  • 27
  • I would post your `DPSImporterServiceImpl#toString` implementation. It may represent a class-scoped state rather than instance. – Mena Jul 01 '15 at 11:22
  • seems to me like the `toString()` implementation of `DPSImporterServiceImpl` class is not implementated correctly? – Sharon Ben Asher Jul 01 '15 at 11:23
  • can you post code of DPSImporterServiceImpl – Shekhar Khairnar Jul 01 '15 at 11:27
  • well the code of the `DPSImporterServiceImpl ` is rather complex. The `toString()` method is not a problem, when I comment it out I get this log: Thread: 1435748953925/java.util.concurrent.FutureTask@7d137980 Waiting over for: mypackage.service.impl.DPSImporterServiceImpl@2c9371e Thread: 1435748971395/java.util.concurrent.FutureTask@295b7fd2 Waiting over for: mypackage.service.impl.DPSImporterServiceImpl@2c9371e So it's still the same object. – Erando Jul 01 '15 at 11:50
  • You say the map definitely doesn't contain identic objects... ok, the map contains Futures, not DPSImporterServiceImpl . Maybe DPSImporterServiceImpl however is unique? Like singleton? How are they created? – Joel Jul 03 '15 at 18:51
  • The output would be plausible if you have a map with two different keys mapping to two different futures, but both futures came from two threads where call() returned the same object... Different futures may hold the same object reference - and there could be plenty of other explanations. – Christian Fries Jul 03 '15 at 18:52
  • @Joel, that's exaclty what happend... thank you! – Erando Jul 15 '15 at 08:47

1 Answers1

0

Well, the following snippet works as expected:

Map<String, Future<String>> map = new HashMap<>();

ExecutorService service = new ScheduledThreadPoolExecutor(1);

Future<String> future1 = service.submit(() -> {
    Thread.sleep(1000);
    return "1";
});
Future<String> future2 = service.submit(() -> {
    Thread.sleep(1000);
    return "2";
});

map.put("1", future1);
map.put("2", future2);

for (Map.Entry<String, Future<String>> entry : map.entrySet()) {
    System.out.println("Thread: " + entry.getKey() + "/" + entry.getValue());
    Future<String> fut = entry.getValue();
    try {
        String imp = fut.get();
        System.out.println("Waiting over for: " + imp);
    } catch (InterruptedException | ExecutionException e) {
        e.printStackTrace();
    }
}

service.shutdown();

Seems to me that the problem might be in DPSImporterServiceImpl or in the way these futures in the map are obtained.