pgras правильно, что неизменность исправит ситуацию, но это также будет сложно. Вы можете просто заблокировать все это, но это может быть проблемой производительности. Я могу придумать две хорошие идеи.
Во-первых, используйте ReadWriteLock (для чего требуется 1.5 или более поздняя версия). Поскольку ваша контрольная точка может получить блокировку чтения, она может быть уверена, что все в порядке, но когда никто не читает, производительность чтения должна быть довольно хорошей. Это все еще довольно грубая блокировка, так что вы также можете сделать # 2 ...
Во-вторых, разбить вещи. У каждой области программы может быть своя собственная карта (карта для графического интерфейса, карта для пользовательских настроек, карта для аппаратных настроек и т. Д.). У каждого будет замок, и все пойдет как обычно. Когда приходит время для контрольной точки, контрольная точка захватывает ВСЕ блокировки (чтобы все было согласованно), а затем выполняет свою работу. Подвох здесь в том, что вы определили порядок захвата замков (скажем, в алфавитном порядке), иначе вы получите тупики.
Если карты ортогональны друг другу (обновления одной не требуют обновлений для другой, чтобы быть непротиворечивыми), то самым простым может быть отправка обновлений на центральную «резервную» карту в контрольной точке, мало чем отличающуюся от чего-либо Вы описали.
Мой самый большой вопрос к вам: насколько это проблема (с точки зрения производительности)? Являются ли обновления очень частыми или редкими? Это помогло бы что-то посоветовать, поскольку моя последняя идея (предыдущий абзац) может быть медленной, но это легко и может не иметь значения.
Существует фантастическая книга под названием Параллелизм Java на практике , которая в основном представляет собой библию потоков Java. В нем обсуждается, как выяснить такие вещи и стратегии, чтобы избежать проблем или облегчить их решение. Если вы собираетесь делать больше потоков, это очень полезное чтение.
На самом деле, если ваши ключевые значения ортогональны друг другу, тогда все действительно просто. Интерфейс ConcurrentMap (существуют реализации, такие как ConcurrentHashMap ) решит ваши проблемы, поскольку они могут вносить изменения атомарно, поэтому читатели не увидят противоречивые данные. Но если у вас есть две (или более) клавиши, которые должны быть обновлены одновременно, это не покроет вас.
Надеюсь, это поможет. Потоковый доступ к разделяемым структурам данных - сложная задача.