简体   繁体   中英

java and threads: very strange behaviour

        private synchronized Map<Team, StandingRow> calculateStanding() {
          System.out.println("Calculate standing for group " + getName());
          Map<Team, StandingRow> standing = new LinkedHashMap<Team, StandingRow>();

          for (Team team : teams) {
           standing.put(team, new StandingRow(team));
          }

          StandingRow homeTeamRow, awayTeamRow;
          for (Match match : matches.values()) {

           homeTeamRow = standing.get(match.getHomeTeam());
           awayTeamRow = standing.get(match.getAwayTeam());

           System.out.println("Contains key for " + match.getHomeTeam() + ": " + standing.containsKey(match.getHomeTeam()));
           System.out.println("Contains key for " + match.getAwayTeam() + ": " + standing.containsKey(match.getAwayTeam()));
                }
        }

This is my code. matches contains 6 elements, but the problem is that after two matches no keys are anymore found in the standing map.

The output is for example

Contains key for Zuid-Afrika: true
Contains key for Mexico: true
Contains key for Uruguay: true
Contains key for Frankrijk: true
Contains key for Zuid-Afrika: false
Contains key for Uruguay: false
Contains key for Frankrijk: false
Contains key for Mexico: false
Contains key for Mexico: false
Contains key for Uruguay: false
Contains key for Frankrijk: false
Contains key for Zuid-Afrika: false

This is in a threaded environment, but the method is synchronized so I thought that this would not give a problem? I have also a simple unit test for this method and that works well.

This is almost surely not a threading issue. I'm all but certain that the problem is in your Team class. It's probably not implementing hashCode() / equals() the right way. Review the javadoc for these two methods and implement them accordingly.

Can you give the details of the Team and the Match classes? Are they implementing equals() and hashCode() ?

Since Team and Match are your own classes, you have to tell java how it should match (decide whether they are equal )

You do that using equals() and hashCode() . See also this article .

Assuming you have implemented equals() and hashCode() correctly , your method looks fine to me.

The big question is: Where does teams and matches come from and how are they filled?

If teams and matches are changed by different threads without synchronization on the same monitor, you could get race conditions there.

Try to sync the methods that are changing matches and teams also.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM