У нас есть приложение, которое использовало экземпляр java.util.HashMap
, который - через различные косвенные отношения - делится так, чтобы несколько потоков обращались к нему одновременно. Мы зафиксировали это на данный момент, поскольку мы знаем, что java.util.HashMap
не является потокобезопасным и не должен быть доступен одновременно.HashMap зависает при одновременном доступе
До этого исправления, и поэтому мы выяснили, у нас было обновление в JDK (в IBM JDK 7 SR3) и после что обновления мы испытали случайные зависания во время ПОЛУЧИТЬ операций этого экземпляра HashMap (зависание происходит в методе getEntry()
.)
Из любопытства я хотел бы знать, что происходит внутри HashMap, что вызывает зависание. Какая разница в реализации, которая влияет на поведение при одновременном доступе?
Что касается реализации HashMap, IBM JDK такой же, как у Oracle JDK и OpenJDK, который снова отличается от версии Java8 (с использованием datastructure Node
).
Я считаю, что difference between java7u40 b43 vs b147 представляет собой изменение, которое было внесено с обновлением.
Мое текущее предположение, причиной зависание связано с изменением метода addEntry
, переходя от надстройки первого-размер-после в изменение размера-первых, надстройку после.
Но есть ли у кого-то точное понимание, что именно происходит во время одновременного доступа?
Гонки данных по своему определению непредсказуемы и случайны. Изменения в JDK, возможно, были небольшим изменением, где-то полностью не связанным, что заставило некоторый процесс нанести наносекунду дольше, раздражая проблему. Скорее всего, вопрос о том, что там все время, но перешел от одного в несколько миллионов шансов на одного в несколько тысяч. Не воссоздавая проблему и принимая дамп потока, почти невозможно определить причину. Безопасность нитей не может быть доказана путем тестирования, но только путем тщательного анализа кода. –
В 'HashMap' нет методов' getEntry() 'и' addEntry() '. Ты уверен, что там ты повесишь? –
@ OlivierGrégoire есть внутри. –