Бесконечный цикл в кэшированной коллекции в многопоточной среде - PullRequest
2 голосов
/ 09 сентября 2011

Мое приложение работает на 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;
}

1 Ответ

1 голос
/ 09 сентября 2011

EHCache никоим образом не изменяет ваши объекты. Есть одно исключение: если у вас есть дисковый кеш (то есть кеш, который может переполниться на диск), EHCache будет сериализовывать ваши объекты, записывать их на диск и загружать снова, если они необходимы.

Таким образом, если существует проблема с сериализацией ваших объектов и , вы настроили EHCache на распространение, это может вызвать проблемы, но это не похоже на вашу проблему.

Я предполагаю, что несколько объектов с одинаковым идентификатором помещаются в кэш или объекты добавляются в кэш до их полной инициализации.

Как это отладить?

  1. Используйте Collections.unmodifiable*() для получения ошибок, если кто-то пытается изменить коллекцию после добавления ее в кэш.

  2. Сохраните hashCode() коллекции и подтвердите ее. hashCode() изменяется, если a) изменяется коллекция или b) если hashCode() объекта в коллекции изменяется.

Особенно последний является хорошим источником непредвиденных проблем: люди используют неконечные поля в hashCode (), добавляют объекты в наборы / карты, и происходят странные вещи.

...