2014-12-10 2 views
3

Скажем, у меня есть две хэш-карты hashMap1 и hashMap2 и многопоточная параллельная Java-программа. Если я помещаю синхронизированный блоксинхронизированное ключевое слово - блокирует ли он два объекта?

synchronized(hashMap1) { 
hashMap1.put(5, "Hello"); 
hashMap2.put(10, "Hi"); 
} 

Поскольку только один поток сразу может получить доступ к hashMap1, будет только один поток будет в состоянии получить доступ hashMap2? Я по существу спрашиваю, будет ли hashMap2 защищен от нескольких потоков, обращающихся к нему сразу, как и hashMap1.

Спасибо!

ответ

0

Ответ зависит от вашего дизайна приложения. В конце концов, синхронизация является концепцией выбора - любой поток может выбрать игнорировать блокировки и просто получать доступ к общим объектам независимо.

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

Может быть яснее, если будущие сопровождающие должны взять блокировки на обоих объектах перед их работой.

+3

Или использовать третий объект для блокировки обоих. Остерегайтесь блокировки тупиков ... – vikingsteve

+0

@vikingsteve Хорошая точка, это действительно может быть лучше. –

4

Нет, synchronized не «блокирует объекты». Что делает ваш блок кода, требуется поток для блокировки hashMap1, прежде чем он сможет войти в блок. hashMap1 сам по себе не «заблокирован», за исключением того, что его монитор приобретается. (Может быть, лучше назвать это монитором, чем блокировкой). Монитор - это то, что все объекты имеют, сам по себе он не делает ничего, чтобы контролировать доступ к объекту, к которому он принадлежит. Если hashMap2 доступен в другом месте, этот синхронизированный блок не делает ничего, чтобы это предотвратить.

Назначение синхронизированного блока - потребовать, чтобы поток приобрел монитор. Во всех местах, где вы хотите, чтобы этот ресурс был защищен от одновременного доступа, требуется потребовать принятия той же блокировки. Это блоки кода, защищенные с помощью synchronized, указывающие, когда нужно использовать объект блокировки, который контролирует доступ.

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

public class Foo { 
    private final Object LOCK = new Object(); 

    private Map hashMap1 = new HashMap(); 
    private Map hashMap2 = new HashMap(); 

    public void doStuff() { 
     synchronized(LOCK) { 
      ... // do stuff with hashMap1 and hashMap2 
     } 
    } 
} 

Сохраняя доступ к блокировка, закрытая для объекта, означает, что объект может ограничить, кто может получить блокировку (в отличие от synchronized(this)). Также не используйте такие вещи, как «Строки» или «Булевы», которые могут быть интернированы, кэшированы или иным образом доступны из других частей программы.

0

Ключевое слово synchronized заставляет поток получать блокировку при входе в метод, только один поток может одновременно выполнять этот метод (для данного экземпляра объекта, если он не является статическим методом).

В вашей ситуации до тех пор, пока внутри метода synchronized это единственное место, где hashmap2 изменен, тогда да, он будет защищен сразу от нескольких потоков. Однако, если hashmap2 модифицируется где-то еще в дополнение к методу , нет гарантии, что hashmap2 будет защищен.

Смежные вопросы