Мое приложение работает на tomcat со средой Spring и Hibernate.Он использует EHCache в качестве поставщика кеша на уровне обслуживания.Это означает, что объекты, созданные классами обслуживания, помещаются в кеш.(Не спящие объекты Dao).
В этих кэшированных объектах есть несколько объектов коллекции (HashSet, ArrayList, HashMap).Ни один из них не является синхронизированной коллекцией.Все они не являются поточно-ориентированными, но они не модифицируются приложением после помещения их в кеш.
Во многих случаях, когда я перебираю эту коллекцию, я обнаружил бесконечный цикл.Некоторые из циклов являются циклами итераторов, а некоторые являются старыми для циклов, запускаемых на основе индекса int.
Мне удалось преодолеть один бесконечный цикл, заменив HashSet на Collections.synchronizedSet (new HashSet ()).Но я не понимаю реальной проблемы использования обычного HashSet, поскольку он никогда не изменяется приложением.(Изменяет ли EHCache их?)
Пожалуйста, объясните мне, есть ли здесь какие-либо проблемы с использованием не поточно-безопасных коллекций.
public class HotelDetails implements Serializable { /*Objects in the cache */
private static final long serialVersionUID = 1L;
.....
private Set<String> facilities = new HashSet<String>();
}
После бесконечного запуска цикла и удаления кучи
if (hotelDetails.getFacilities() != null && hotelDetails.getFacilities().size() > 0) {
for (String fac : hotelDetails.getFacilities()) {
TFacility f = of.createTFacility();
f.setCode(fac);
f.setValue(fac);
facilities.getFacility().add(f);
}
}
однажды заменив HashSet, проблема решена
public class HotelDetails implements Serializable { /*Objects in the cache */
private static final long serialVersionUID = 1L;
.....
private Set<String> facilities = Collections.synchronizedSet(new HashSet<String>());
}
И это еще один
private int getRatesStartIndex(GsRoomRate gsRoomRate, List<GsRate> gsRates, Date travelStart) {
Integer startIndex = gsRoomRate.getGsRateIndexes().get(travelStart);
if (startIndex==null) {
for (startIndex=0; startIndex<gsRates.size(); startIndex++) {
GsRate gsRate = gsRates.get(startIndex);
if (travelStart.between(gsRate.getStartDate(), gsRate.getEndDate())) {
gsRoomRate.getGsRateIndexes().put(travelStart, startIndex);
break;
}
}
if (startIndex>=gsRates.size()) startIndex = 0;
}
return startIndex;
}
public class GsRoomRate implements Serializable { /*Objects in the cache */
private static final long serialVersionUID = 1L;
private List<GsRate> gsRates = new ArrayList<GsRate>();
private Map<Date, Integer> gsRateIndexes = new HashMap<Date, Integer>();
}
public class GsRate implements Serializable { /*Objects in the cache */
private static final long serialVersionUID = 1L;
private RBADate startDate;
private RBADate endDate;
}