Что-то случилось, что я не уверен, что это возможно. Очевидно, потому что я видел это, но мне нужно найти основную причину, и я надеялся, что вы все можете помочь.
У нас есть система, которая ищет широту и долготу для почтового индекса. Вместо того, чтобы обращаться к нему каждый раз, мы кешируем результаты в дешевом кеше HashTable в памяти, поскольку широта и длина почтового индекса имеют тенденцию меняться реже, чем мы выпускаем.
В любом случае, хеш окружен классом, в котором есть методы get и add, которые синхронизированы. Мы получаем доступ к этому классу как к одиночке.
Я не утверждаю, что это лучшая установка, но это то, где мы находимся. (Я планирую изменить, чтобы обернуть карту в вызов Collections.synchronizedMap () как можно скорее.)
Мы используем этот кеш в многопоточной среде, где мы нанизываем 2 вызова на 2 почтовых индекса (чтобы мы могли вычислить расстояние между ними). Иногда это происходит почти в одно и то же время, поэтому вполне возможно, что оба звонка получают доступ к карте одновременно.
Совсем недавно у нас произошел инцидент, когда два разных почтовых индекса вернули одно и то же значение. Предполагая, что начальные значения на самом деле были разными, есть ли способ, что запись значений в карту приведет к тому, что одно и то же значение будет записано для двух разных ключей? Или есть ли способ, при котором 2 «получает» может пересечь провода и случайно вернуть то же значение?
Единственное другое объяснение, которое у меня есть, заключается в том, что исходные данные были повреждены (неправильные значения), но это кажется маловероятным.
Любые идеи будут оценены.
Спасибо,
Питер
(PS: дайте мне знать, если вам нужна дополнительная информация, код и т. Д.)
public class InMemoryGeocodingCache implements GeocodingCache
{
private Map cache = new HashMap();
private static GeocodingCache instance = new InMemoryGeocodingCache();
public static GeocodingCache getInstance()
{
return instance;
}
public synchronized LatLongPair get(String zip)
{
return (LatLongPair) cache.get(zip);
}
public synchronized boolean has(String zip)
{
return cache.containsKey(zip);
}
public synchronized void add(String zip, double lat, double lon)
{
cache.put(zip, new LatLongPair(lat, lon));
}
}
public class LatLongPair {
double lat;
double lon;
LatLongPair(double lat, double lon)
{
this.lat = lat;
this.lon = lon;
}
public double getLatitude()
{
return this.lat;
}
public double getLongitude()
{
return this.lon;
}
}