Вам нужно запустить обе операции в пределах одного synchronized
блока. Стоит отметить, что в вашем примере вы определили карты статически, а метод process()
- это метод экземпляра. Синхронизация метода будет означать, что вызовы на этот экземпляр будут синхронизированы, но вызовы для двух разных экземпляров не будут (поскольку блокировка, используемая при применении ключевого слова synchronized для метода, фактически равна this
). Вы можете либо сделать метод process() статическим, либо использовать блок synchronized(Test.class) {}
, чтобы убедиться, что нет гонок.
Вам также нужно быть осторожным в том, как вы показываете карты клиентам - если вы предлагаете их как свойства, то я бы, вероятно, обернул их Collections.unmodifiableMap(), чтобы гарантировать, что больше ничего не может пойти и винт с ними, пока вы не смотрите - однако это не полностью защищает от клиентов, имеющих «странное» время, поскольку они все еще видят, что изменения происходят в потенциально опасном режиме. Таким образом, я бы, вероятно, также объявлять типы, как ConcurrentHashMap, чтобы сделать вещи немного безопаснее (хотя есть еще некоторые опасные операции, такие как обмен итератора между потоками)
Это действительно зависит от того, какие гарантии параллельности вы хотите иметь. –
Для этого вы можете использовать 'Lock', что может быть чрезмерным или одним синхронизированным методом. –