java和线程:非常奇怪的行为
这是在线程环境中,但是方法是同步的,所以我认为这不会产生问题?对于这种方法,我还有一个简单的单元测试,效果很好。这几乎肯定不是线程问题。我几乎可以肯定问题出在你的团队课上。它可能没有以正确的方式实现hashCode/equals。查看javadoc中的这两种方法,并相应地实现它们。您能给出球队和比赛类别的详细信息吗? 他们是否实现了equals和hashCode 因为Team和Match是您自己的类,所以您必须告诉java它应该如何匹配来决定它们是否相等java和线程:非常奇怪的行为,java,thread-safety,Java,Thread Safety,这是在线程环境中,但是方法是同步的,所以我认为这不会产生问题?对于这种方法,我还有一个简单的单元测试,效果很好。这几乎肯定不是线程问题。我几乎可以肯定问题出在你的团队课上。它可能没有以正确的方式实现hashCode/equals。查看javadoc中的这两种方法,并相应地实现它们。您能给出球队和比赛类别的详细信息吗? 他们是否实现了equals和hashCode 因为Team和Match是您自己的类,所以您必须告诉java它应该如何匹配来决定它们是否相等 你可以用和来做。另请参见。假设您已经实现
你可以用和来做。另请参见。假设您已经实现了equals和hashCode,您的方法在我看来很好 最大的问题是:球队和比赛从何而来,他们是如何填补的 如果团队和比赛由不同的线程更改,而没有在同一个监视器上同步,则可以在那里获得比赛条件
尝试同步正在更改比赛和球队的方法。此方法甚至不会编译,因为不会返回。请告诉我们实际的代码。团队是否被其他线程修改?您是否在团队类中为equals和hashCode提供了实现?他可能正确地实现了它们。因为如果他在将团队对象用作映射中的键后更改了它,那么即使使用正确的实现,他也会遇到这些问题,特别是使用正确的实现。顺便说一下:如果你是天才,JavaDoc足以正确实现它们,《有效Java》第3章更详细地描述了问题和解决方案:正如Joachim所说,如果团队不是不可变的,并被用作映射中的键,那么即使正确地实现equals/hashcode,也可能存在问题
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()));
}
}
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