2011-12-16 7 views
3

У меня есть статический метод, как следуетявляется экземпляром класса внутри статического метод Потокобезопасной

public static void foo(){ 
    final ClassA a = new ClassA(); 
} 

У меня есть два хэш-карты внутри CLASSA.

Являются ли эти хэш-карты потоками безопасными ...?

+0

Непонятно, как эти карты используются и определяются. HashMap не является потокобезопасным. Но см. Параллельные хэш-карты: http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/ConcurrentHashMap.html – Adrian

ответ

0

Неясно, хотите ли вы получить доступ к хэш-картам внутри объекта a с несколькими потоками или вызвать метод foo с несколькими потоками.

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

Во втором случае каждый поток будет иметь другую копию foo в своем стеке и выделить другой экземпляр ClassA. Поэтому они не будут сталкиваться, потому что они будут иметь разные HashMaps для работы.

Просьба пояснить, в каких случаях вы работаете.

0

Класс HashMap не является потокобезопасным.

Обратите внимание, что эта реализация не синхронизирована. Если несколько потоков доступа к этой карте одновременно, и, по меньшей мере, один из потоков изменяет карту структурно, она должна быть синхронизирована внешне

Однако при вызове кода foo вы получите новый ClassA каждый раз, так что две разные потоки, которые вызывают foo, будут иметь доступ к различным экземплярам ClassA. Предполагая, что хэшмапы внутри ClassA не являются статическими или совместно используемыми, код должен работать правильно.

+0

Но является ли новая операция атомой? – chance

+0

Если вы беспокоитесь о файлообменных картах, вы можете использовать Collections.synchronizedMap или ConcurrentHashMap – luketorjussen

+0

@chance, да есть системная блокировка, которая гарантирует, что два потока не смогут распределять кучную память одновременно. – Tudor

0

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

Но если вы хотите иметь одну и ту же карту хэша для всех потоков, попробуйте сделать это synchronized.

3

если HashMaps внутри classA не являются статичными (создан новым для каждого нового ClassA()), то вы можете вызвать Foo из нескольких потоков и гарантировать, что только один поток будет когда-либо работать через HashMaps внутри экземпляра classA, созданный для этой нити ,

1

Я не согласен (что мне не хватает)?

Внутри метода создается новый экземпляр ClassA. Даже если несколько потоков обращаются к методу, у каждого будет уникальный HashMap для работы.

Если ClassA был переменной экземпляра, это было бы иначе. Кроме того, если ClassA будет обращаться к картам одновременно, возникнут проблемы с потоками.

Также, если карты являются статическими, несколько экземпляров ClassA будут иметь к нему доступ, и да, это было бы проблематично.

0

HashMap не поточно-, но при условии, что вы никогда не публиковать экземпляр a, ни его два хэш-карты за пределами foo(), то все три ограничены одним потоком и не должны быть потокобезопасным.

Если вы публикуете a или его хэш-карты или если хэш-карты являются статическими элементами ClassA, вы должны обеспечить безопасность потоков. Предполагая, что нет никаких инвариантов, связанных как с хэш-картами, так и с некоторыми другими переменными состояния, вы можете просто использовать ConcurrentHashMap для достижения этого. Если есть такие инварианты, вы должны синхронизировать, идеально как можно ближе к переменным состояния, то есть в ClassA, а не в foo().